
#Область ПрограммныйИнтерфейс

#Область РасписаниеРегЗаданий

// Преобразует РасписаниеРегламентногоЗадания в структуру.
//
// Параметры:
//  Расписание - РасписаниеРегламентногоЗадания - исходное расписание.
// 
// Возвращаемое значение:
//  Структура - расписание в виде структуры.
//
Функция РасписаниеВСтруктуру(Знач Расписание) Экспорт

	ЗначениеРасписания = Расписание;
	Если ЗначениеРасписания = Неопределено Тогда
		ЗначениеРасписания = Новый РасписаниеРегламентногоЗадания;
	КонецЕсли;
	СписокПолей = "ВремяЗавершения,ВремяКонца,ВремяНачала,ДатаКонца,ДатаНачала,ДеньВМесяце,ДеньНеделиВМесяце,"
		+ "ДниНедели,ИнтервалЗавершения,Месяцы,ПаузаПовтора,ПериодНедель,ПериодПовтораВТечениеДня,ПериодПовтораДней";
	Результат = Новый Структура(СписокПолей);
	ЗаполнитьЗначенияСвойств(Результат, ЗначениеРасписания, СписокПолей);
	ДетальныеРасписанияДня = Новый Массив;
	Для Каждого РасписаниеДля Из Расписание.ДетальныеРасписанияДня Цикл
		ДетальныеРасписанияДня.Добавить(РасписаниеВСтруктуру(РасписаниеДля));
	КонецЦикла;
	Результат.Вставить("ДетальныеРасписанияДня", ДетальныеРасписанияДня);
	Возврат Результат;

КонецФункции

// Преобразует структуру в РасписаниеРегламентногоЗадания.
//
// Параметры:
//  СтруктураРасписания - Структура - расписание в виде структуры.
// 
// Возвращаемое значение:
//  РасписаниеРегламентногоЗадания - расписание.
//
Функция СтруктураВРасписание(Знач СтруктураРасписания) Экспорт

	Если СтруктураРасписания = Неопределено Тогда
		Возврат Новый РасписаниеРегламентногоЗадания;
	КонецЕсли;
	СписокПолей = "ВремяЗавершения,ВремяКонца,ВремяНачала,ДатаКонца,ДатаНачала,ДеньВМесяце,ДеньНеделиВМесяце,"
		+ "ДниНедели,ИнтервалЗавершения,Месяцы,ПаузаПовтора,ПериодНедель,ПериодПовтораВТечениеДня,ПериодПовтораДней";
	Результат = Новый РасписаниеРегламентногоЗадания;
	ЗаполнитьЗначенияСвойств(Результат, СтруктураРасписания, СписокПолей);
	ДетальныеРасписанияДня = Новый Массив;
	Для Каждого Расписание Из СтруктураРасписания.ДетальныеРасписанияДня Цикл
		ДетальныеРасписанияДня.Добавить(СтруктураВРасписание(Расписание));
	КонецЦикла;
	Результат.ДетальныеРасписанияДня = ДетальныеРасписанияДня;
	Возврат Результат;

КонецФункции


#КонецОбласти

#Область УниверсальныеКоллекции

// Дополняет массив МассивПриемник значениями из массива МассивИсточник.
//
// Параметры:
//  МассивПриемник - Массив из Произвольный - массив, в который необходимо добавить значения.
//  МассивИсточник - Массив из Произвольный - массив значений для заполнения.
//  ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения.
//
Процедура ДополнитьМассив(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт

	Если ТолькоУникальныеЗначения Тогда

		УникальныеЗначения = Новый Соответствие;

		Для Каждого Значение Из МассивПриемник Цикл
			УникальныеЗначения.Вставить(Значение, Истина);
		КонецЦикла;

		Для Каждого Значение Из МассивИсточник Цикл
			Если УникальныеЗначения[Значение] = Неопределено Тогда
				МассивПриемник.Добавить(Значение);
				УникальныеЗначения.Вставить(Значение, Истина);
			КонецЕсли;
		КонецЦикла;

	Иначе

		Для Каждого Значение Из МассивИсточник Цикл
			МассивПриемник.Добавить(Значение);
		КонецЦикла;

	КонецЕсли;

КонецПроцедуры

// Возвращает разность массивов. Разностью двух массивов является массив, содержащий
// все элементы первого массива, не существующие во втором массиве.
//
// Параметры:
//  Массив - Массив из Произвольный - массив элементов, из которого необходимо выполнить вычитание;
//  МассивВычитания - Массив из Произвольный- массив элементов, который будет вычитаться.
// 
// Возвращаемое значение:
//  Массив из Произвольный - разностью двух массивов.
//
// Пример:
//	//А = [1, 3, 5, 7];
//	//В = [3, 7, 9];
//	Результат = ОбщегоНазначенияКлиентСервер.РазностьМассивов(А, В);
//	//Результат = [1, 5];
//
Функция РазностьМассивов(Знач Массив, Знач МассивВычитания) Экспорт
	
	Результат = Новый Массив;
	Для Каждого Элемент Из Массив Цикл
		Если МассивВычитания.Найти(Элемент) = Неопределено Тогда
			Результат.Добавить(Элемент);
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

// Возвращает значение свойства структуры.
//
// Параметры:
//   Структура - Структура, ФиксированнаяСтруктура - Объект, из которого необходимо прочитать значение ключа.
//   Ключ - Строка - Имя свойства структуры, для которого необходимо прочитать значение.
//   ЗначениеПоУмолчанию - Произвольный - Необязательный. Возвращается когда в структуре нет значения по указанному
//                                        ключу.
//       Для скорости рекомендуется передавать только быстро вычисляемые значения (например примитивные типы),
//       а инициализацию более тяжелых значений выполнять после проверки полученного значения (только если это
//       требуется).
//
// Возвращаемое значение:
//   Произвольный - Значение свойства структуры. ЗначениеПоУмолчанию если в структуре нет указанного свойства.
//
Функция СвойствоСтруктуры(Структура, Ключ, ЗначениеПоУмолчанию = Неопределено) Экспорт

	Если Структура = Неопределено Тогда
		Возврат ЗначениеПоУмолчанию;
	КонецЕсли;

	Результат = ЗначениеПоУмолчанию;
	Если Структура.Свойство(Ключ, Результат) Тогда
		Возврат Результат;
	Иначе
		Возврат ЗначениеПоУмолчанию;
	КонецЕсли;

КонецФункции

// Создает копию значения типа Структура, рекурсивно, с учетом типов значений свойств. 
// Если свойства структуры содержат значения объектных типов (СправочникОбъект, ДокументОбъект и т.п.),
// то их содержимое не копируются, а возвращаются ссылки на исходный объект.
//
// Параметры:
//  СтруктураИсточник - Структура - копируемая структура.
// 
// Возвращаемое значение:
//  Структура - копия исходной структуры.
//
Функция СкопироватьСтруктуру(СтруктураИсточник) Экспорт

	СтруктураРезультат = Новый Структура;

	Для Каждого КлючИЗначение Из СтруктураИсточник Цикл
		СтруктураРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение));
	КонецЦикла;

	Возврат СтруктураРезультат;

КонецФункции

// Дополняет структуру значениями из другой структуры.
//
// Параметры:
//   Приемник - Структура - коллекция, в которую будут добавляться новые значения.
//   Источник - Структура - коллекция, из которой будут считываться пары Ключ и Значение для заполнения.
//   Заменять - Булево, Неопределено - что делать в местах пересечения ключей источника и приемника:
//                                       Истина - заменять значения приемника (самый быстрый способ),
//                                       Ложь   - не заменять значения приемника (пропускать),
//                                       Неопределено - значение по умолчанию. Бросать исключение.
//
Процедура ДополнитьСтруктуру(Приемник, Источник, Заменять = Неопределено) Экспорт

	Для Каждого Элемент Из Источник Цикл
		Если Заменять <> Истина И Приемник.Свойство(Элемент.Ключ) Тогда
			Если Заменять = Ложь Тогда
				Продолжить;
			Иначе
				ВызватьИсключение СтрШаблон(НСтр("ru = 'Пересечение ключей источника и приемника: ""%1"".'"),
					Элемент.Ключ);
			КонецЕсли;
		КонецЕсли;
		Приемник.Вставить(Элемент.Ключ, Элемент.Значение);
	КонецЦикла;

КонецПроцедуры

// Создает полную копию структуры, соответствия, массива, списка или таблицы значений, рекурсивно, 
// с учетом типов дочерних элементов. При этом содержимое значений объектных типов 
// (СправочникОбъект, ДокументОбъект и т.п.) не копируются, а возвращаются ссылки на исходный объект.
//
// Параметры:
//  Источник - Структура, Соответствие из Произвольный, Массив, СписокЗначений, ТаблицаЗначений - объект, который необходимо 
//             скопировать.
//
// Возвращаемое значение:
//  Структура, Соответствие из Произвольный, Массив, СписокЗначений, ТаблицаЗначений - копия объекта, переданного в параметре Источник.
//
//@skip-check doc-comment-collection-item-type
Функция СкопироватьРекурсивно(Источник) Экспорт

	Перем Приемник;

	ТипИсточника = ТипЗнч(Источник);

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	Если ТипИсточника = Тип("ТаблицаЗначений") Тогда
		Возврат Источник.Скопировать();
	КонецЕсли;
#КонецЕсли
	Если ТипИсточника = Тип("Структура") Тогда
		Приемник = СкопироватьСтруктуру(Источник);
	ИначеЕсли ТипИсточника = Тип("Соответствие") Тогда
		Приемник = СкопироватьСоответствие(Источник);
	ИначеЕсли ТипИсточника = Тип("Массив") Тогда
		Приемник = СкопироватьМассив(Источник);
	ИначеЕсли ТипИсточника = Тип("СписокЗначений") Тогда
		Приемник = СкопироватьСписокЗначений(Источник);
	Иначе
		Приемник = Источник;
	КонецЕсли;

	//@skip-check constructor-function-return-section
	Возврат Приемник;

КонецФункции

// Создает копию значения типа Соответствие, рекурсивно, с учетом типов значений.
// Если значения соответствия содержат значения объектных типов (СправочникОбъект, ДокументОбъект и т.п.),
// то их содержимое не копируются, а возвращаются ссылки на исходный объект.
//
// Параметры:
//  СоответствиеИсточник - Соответствие - соответствие, копию которого необходимо получить.
// 
// Возвращаемое значение:
//  Соответствие - копия исходного соответствия.
//
//@skip-check doc-comment-collection-item-type
Функция СкопироватьСоответствие(СоответствиеИсточник) Экспорт

	СоответствиеРезультат = Новый Соответствие;

	Для Каждого КлючИЗначение Из СоответствиеИсточник Цикл
		СоответствиеРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение));
	КонецЦикла;

	Возврат СоответствиеРезультат;

КонецФункции

// Создает копию значения типа Массив, рекурсивно, с учетом типов значений элементов массива.
// Если элементы массива содержат значения объектных типов (СправочникОбъект, ДокументОбъект и т.п.),
// то их содержимое не копируются, а возвращаются ссылки на исходный объект.
//
// Параметры:
//  МассивИсточник - Массив - массив, копию которого необходимо получить.
// 
// Возвращаемое значение:
//  Массив - копия исходного массива.
//
//@skip-check doc-comment-collection-item-type
Функция СкопироватьМассив(МассивИсточник) Экспорт

	МассивРезультат = Новый Массив;

	Для Каждого Элемент Из МассивИсточник Цикл
		МассивРезультат.Добавить(СкопироватьРекурсивно(Элемент));
	КонецЦикла;

	Возврат МассивРезультат;

КонецФункции

// Создает копию значения типа СписокЗначений, рекурсивно, с учетом типов его значений.
// Если в списке значений есть значения объектных типов (СправочникОбъект, ДокументОбъект и т.п.),
// то их содержимое не копируются, а возвращаются ссылки на исходный объект.
//
// Параметры:
//  СписокИсточник - СписокЗначений - список значений, копию которого необходимо получить.
// 
// Возвращаемое значение:
//  СписокЗначений - копия исходного списка значений.
//
//@skip-check doc-comment-collection-item-type
Функция СкопироватьСписокЗначений(СписокИсточник) Экспорт

	СписокРезультат = Новый СписокЗначений;

	Для Каждого ЭлементСписка Из СписокИсточник Цикл
		СписокРезультат.Добавить(СкопироватьРекурсивно(ЭлементСписка.Значение), ЭлементСписка.Представление,
			ЭлементСписка.Пометка, ЭлементСписка.Картинка);
	КонецЦикла;

	Возврат СписокРезультат;

КонецФункции



#КонецОбласти

#Область КонтекстИсполнения

// Доступные контексты платформы.
// 
// Возвращаемое значение:
//  Структура - Доступные контексты платформы:
// * Сервер - Строка - 
// * ТолстыйКлиент - Строка - 
// * ТонкийКлиент - Строка - 
// * ВнешнееСоединение - Строка - 
// * ВебКлиент - Строка - 
// * МобильныйКлиент - Строка - 
// * МобильноеПриложениеКлиент - Строка - 
// * МобильноеПриложениеСервер - Строка - 
// * МобильныйАвтономныйСервер - Строка - 
// * Интеграция - Строка - 
// * Неопределенный - Строка - 
Функция ДоступныеКонтекстыПлатформы() Экспорт
	Описание = Новый Структура;
	Описание.Вставить("Сервер","Сервер");
	Описание.Вставить("ТолстыйКлиент","ТолстыйКлиент");
	Описание.Вставить("ТонкийКлиент","ТонкийКлиент");
	Описание.Вставить("ВнешнееСоединение","ВнешнееСоединение");
	Описание.Вставить("ВебКлиент","ВебКлиент");
	Описание.Вставить("МобильныйКлиент","МобильныйКлиент");
	Описание.Вставить("МобильноеПриложениеКлиент","МобильноеПриложениеКлиент");
	Описание.Вставить("МобильноеПриложениеСервер","МобильноеПриложениеСервер");
	Описание.Вставить("МобильныйАвтономныйСервер","МобильныйАвтономныйСервер");
	Описание.Вставить("Интеграция","Интеграция");
	Описание.Вставить("Неопределенный","");
	Возврат Описание;
КонецФункции

// Текущий контекст платформы.
// 
// Возвращаемое значение:
//  Строка - Текущий контекст платформы
//@skip-check bsl-legacy-check-if-preprocessor-part-environments
Функция ТекущийКонтекстПлатформы() Экспорт
	КонтекстыПлатформы = ДоступныеКонтекстыПлатформы();
	#Если Сервер Тогда
		Возврат КонтекстыПлатформы.Сервер;
	#ИначеЕсли ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
		Возврат КонтекстыПлатформы.ТолстыйКлиент;
	#ИначеЕсли ТонкийКлиент Тогда
		Возврат КонтекстыПлатформы.ТонкийКлиент;
	#ИначеЕсли ВнешнееСоединение Тогда
		Возврат КонтекстыПлатформы.ВнешнееСоединение;
	#ИначеЕсли ВебКлиент Тогда
		Возврат КонтекстыПлатформы.ВебКлиент;
	#ИначеЕсли МобильныйКлиент Тогда
		Возврат КонтекстыПлатформы.МобильныйКлиент;
	#ИначеЕсли МобильноеПриложениеКлиент Тогда
		Возврат КонтекстыПлатформы.МобильноеПриложениеКлиент;
//	#ИначеЕсли МобильноеПриложениеСервер Тогда
//		Возврат КонтекстыПлатформы.МобильноеПриложениеСервер;
//	#ИначеЕсли МобильныйАвтономныйСервер Тогда
//		Возврат КонтекстыПлатформы.МобильныйАвтономныйСервер;
//	#ИначеЕсли Интеграция Тогда
//		Возврат КонтекстыПлатформы.Интеграция;
	#Иначе
		Возврат КонтекстыПлатформы.Неопределенный;
	#КонецЕсли
		
КонецФункции

// Это контекст сервера.
// 
// Возвращаемое значение:
//  Булево -  Это контекст сервера
Функция ЭтоКонтекстСервера() Экспорт

	#Если Сервер Тогда
		Возврат Истина;
	#Иначе
		Возврат Ложь;
	#КонецЕсли
КонецФункции

// Это веб клиент.
// 
// Возвращаемое значение:
//  Булево -  Это веб клиент
Функция ЭтоВебКлиент() Экспорт
	#Если ВебКлиент Тогда
	Возврат Истина;
	#Иначе 
	Возврат Ложь;
	#КонецЕсли
КонецФункции

// Это windows.
// 
// Возвращаемое значение:
//  Булево -  Это windows
Функция ЭтоWindows() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Или СистемнаяИнформация.ТипПлатформы
		= ТипПлатформы.Windows_x86_64;
КонецФункции

// Это linux.
// 
// Возвращаемое значение:
//  Булево -  Это linux
Функция ЭтоLinux() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86 Или СистемнаяИнформация.ТипПлатформы
		= ТипПлатформы.Linux_x86_64;
КонецФункции

// Это mac os.
// 
// Возвращаемое значение:
//  Булево -  Это mac os
Функция ЭтоMacOs() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.MacOS_x86 Или СистемнаяИнформация.ТипПлатформы
		= ТипПлатформы.MacOS_x86_64;
КонецФункции

// Это разрядность х86.
// 
// Возвращаемое значение:
//  Булево -  Это разрядность х86
Функция ЭтоРазрядностьХ86() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.MacOS_x86
			Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86
			Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86;
КонецФункции

// Это разрядность х64.
// 
// Возвращаемое значение:
//  Булево -  Это разрядность х64
Функция ЭтоРазрядностьХ64() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.MacOS_x86_64
			Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86_64
			Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64;
КонецФункции

// Поле HTMLПостроено на webkit.
// 
// Возвращаемое значение:
//  Булево -  Поле HTMLПостроено на webkit
Функция ПолеHTMLПостроеноНаWebkit() Экспорт
	Возврат ВерсияПлатформыНеМладше_8_3_14() Или ЭтоLinux()
КонецФункции

#КонецОбласти

#Область Переменные

// Имя переменной корректно.
// 
// Параметры:
//  Имя -Строка -Имя
// 
// Возвращаемое значение:
//  Булево -  Имя переменной корректно
Функция ИмяПеременнойКорректно(Имя) Экспорт
	Если НЕ ЗначениеЗаполнено(Имя) Тогда
		Возврат Ложь;
	КонецЕсли;
	ИмяКорректно = Ложь;
	//@skip-check empty-except-statement
	Попытка
		//@skip-check module-unused-local-variable
		СтруктураТест = Новый Структура(Имя);
		ИмяКорректно=Истина;
	Исключение
	КонецПопытки;
	
	Возврат ИмяКорректно;
КонецФункции

// Текст предупреждения о нерпавильном имени переменной.
// 
// Возвращаемое значение:
//  Строка -  Текст предупреждения о нерпавильном имени переменной
Функция ТекстПредупрежденияОНерпавильномИмениПеременной() Экспорт
	Возврат "Неверное имя колонки! Имя должно состоять из одного слова, начинаться с буквы и не содержать специальных символов кроме ""_"".";
КонецФункции

#КонецОбласти

#Область ДинамическийСписок

////////////////////////////////////////////////////////////////////////////////
// Функции для работы с отборами и параметрами динамических списков.
//

// Найти элемент или группу отбора по заданному имени поля или представлению.
//
// Параметры:
//  ОбластьПоиска - ОтборКомпоновкиДанных, КоллекцияЭлементовОтбораКомпоновкиДанных,
//                  ГруппаЭлементовОтбораКомпоновкиДанных - контейнер
//                  с элементами и группами отбора, например Список.Отбор или группа в отборе.
//  ИмяПоля       - Строка - имя поля компоновки (не используется для групп).
//  Представление - Строка - представление поля компоновки.
//
// Возвращаемое значение:
//  Массив - коллекция отборов.
//
Функция НайтиЭлементыИГруппыОтбора(Знач ОбластьПоиска, Знач ИмяПоля = Неопределено, Знач Представление = Неопределено) Экспорт

	Если ЗначениеЗаполнено(ИмяПоля) Тогда
		ЗначениеПоиска = Новый ПолеКомпоновкиДанных(ИмяПоля);
		СпособПоиска = 1;
	Иначе
		СпособПоиска = 2;
		ЗначениеПоиска = Представление;
	КонецЕсли;

	МассивЭлементов = Новый Массив;

	НайтиРекурсивно(ОбластьПоиска.Элементы, МассивЭлементов, СпособПоиска, ЗначениеПоиска);

	Возврат МассивЭлементов;

КонецФункции

// Добавить группу отбора в коллекцию КоллекцияЭлементов.
//
// Параметры:
//  КоллекцияЭлементов - ОтборКомпоновкиДанных, КоллекцияЭлементовОтбораКомпоновкиДанных,
//                       ГруппаЭлементовОтбораКомпоновкиДанных - контейнер
//                       с элементами и группами отбора, например Список.Отбор или группа в отборе.
//  Представление      - Строка - представление группы.
//  ТипГруппы          - ТипГруппыЭлементовОтбораКомпоновкиДанных - тип группы.
//
// Возвращаемое значение:
//  ГруппаЭлементовОтбораКомпоновкиДанных - группа отбора.
//
Функция СоздатьГруппуЭлементовОтбора(Знач КоллекцияЭлементов, Представление, ТипГруппы) Экспорт

	Если ТипЗнч(КоллекцияЭлементов) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
		КоллекцияЭлементов = КоллекцияЭлементов.Элементы;
	КонецЕсли;

	ГруппаЭлементовОтбора = НайтиЭлементОтбораПоПредставлению(КоллекцияЭлементов, Представление);
	Если ГруппаЭлементовОтбора = Неопределено Тогда
		ГруппаЭлементовОтбора = КоллекцияЭлементов.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	Иначе
		ГруппаЭлементовОтбора.Элементы.Очистить();
	КонецЕсли;

	ГруппаЭлементовОтбора.Представление = Представление;
	ГруппаЭлементовОтбора.Применение = ТипПримененияОтбораКомпоновкиДанных.Элементы;
	ГруппаЭлементовОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
	ГруппаЭлементовОтбора.ТипГруппы = ТипГруппы;
	ГруппаЭлементовОтбора.Использование = Истина;

	Возврат ГруппаЭлементовОтбора;

КонецФункции

// Добавить элемент компоновки в контейнер элементов компоновки.
//
// Параметры:
//  ОбластьДобавления - КоллекцияЭлементовОтбораКомпоновкиДанных - контейнер с элементами и группами отбора,
//                                                                 например, Список.Отбор или группа в отборе.
//  ИмяПоля                 - Строка - имя поля компоновки данных (заполняется всегда).
//  ПравоеЗначение          - Произвольный - сравниваемое значение.
//  ВидСравнения            - ВидСравненияКомпоновкиДанных - вид сравнения.
//  Представление           - Строка - представление элемента компоновки данных.
//  Использование           - Булево - использование элемента.
//  РежимОтображения        - РежимОтображенияЭлементаНастройкиКомпоновкиДанных - режим отображения.
//  ИдентификаторПользовательскойНастройки - Строка - см. ОтборКомпоновкиДанных.ИдентификаторПользовательскойНастройки
//                                                    в синтакс-помощнике.
// Возвращаемое значение:
//  ЭлементОтбораКомпоновкиДанных - элемент компоновки.
//
Функция ДобавитьЭлементКомпоновки(ОбластьДобавления, Знач ИмяПоля, Знач ВидСравнения, Знач ПравоеЗначение = Неопределено,
	Знач Представление = Неопределено, Знач Использование = Неопределено, Знач РежимОтображения = Неопределено,
	Знач ИдентификаторПользовательскойНастройки = Неопределено) Экспорт

	Элемент = ОбластьДобавления.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
	Элемент.ВидСравнения = ВидСравнения;

	Если РежимОтображения = Неопределено Тогда
		Элемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
	Иначе
		Элемент.РежимОтображения = РежимОтображения;
	КонецЕсли;

	Если ПравоеЗначение <> Неопределено Тогда
		Элемент.ПравоеЗначение = ПравоеЗначение;
	КонецЕсли;

	Если Представление <> Неопределено Тогда
		Элемент.Представление = Представление;
	КонецЕсли;

	Если Использование <> Неопределено Тогда
		Элемент.Использование = Использование;
	КонецЕсли;

	// Важно: установка идентификатора должна выполняться
	// в конце настройки элемента, иначе он будет скопирован
	// в пользовательские настройки частично заполненным.
	Если ИдентификаторПользовательскойНастройки <> Неопределено Тогда
		Элемент.ИдентификаторПользовательскойНастройки = ИдентификаторПользовательскойНастройки;
	ИначеЕсли Элемент.РежимОтображения <> РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный Тогда
		Элемент.ИдентификаторПользовательскойНастройки = ИмяПоля;
	КонецЕсли;

	Возврат Элемент;

КонецФункции

// Изменить элемент отбора с заданным именем поля или представлением.
//
// Параметры:
//  ОбластьПоиска - КоллекцияЭлементовОтбораКомпоновкиДанных - контейнер с элементами и группами отбора,
//                                                             например Список.Отбор или группа в отборе.
//  ИмяПоля                 - Строка - имя поля компоновки данных (заполняется всегда).
//  Представление           - Строка - представление элемента компоновки данных.
//  ПравоеЗначение          - Произвольный - сравниваемое значение.
//  ВидСравнения            - ВидСравненияКомпоновкиДанных - вид сравнения.
//  Использование           - Булево - использование элемента.
//  РежимОтображения        - РежимОтображенияЭлементаНастройкиКомпоновкиДанных - режим отображения.
//  ИдентификаторПользовательскойНастройки - Строка - см. ОтборКомпоновкиДанных.ИдентификаторПользовательскойНастройки
//                                                    в синтакс-помощнике.
//
// Возвращаемое значение:
//  Число - количество измененных элементов.
//
Функция ИзменитьЭлементыОтбора(ОбластьПоиска, Знач ИмяПоля = Неопределено, Знач Представление = Неопределено,
	Знач ПравоеЗначение = Неопределено, Знач ВидСравнения = Неопределено, Знач Использование = Неопределено,
	Знач РежимОтображения = Неопределено, Знач ИдентификаторПользовательскойНастройки = Неопределено) Экспорт

	Если ЗначениеЗаполнено(ИмяПоля) Тогда
		ЗначениеПоиска = Новый ПолеКомпоновкиДанных(ИмяПоля);
		СпособПоиска = 1;
	Иначе
		СпособПоиска = 2;
		ЗначениеПоиска = Представление;
	КонецЕсли;

	МассивЭлементов = Новый Массив;

	НайтиРекурсивно(ОбластьПоиска.Элементы, МассивЭлементов, СпособПоиска, ЗначениеПоиска);

	Для Каждого Элемент Из МассивЭлементов Цикл
		Если ИмяПоля <> Неопределено Тогда
			Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
		КонецЕсли;
		Если Представление <> Неопределено Тогда
			Элемент.Представление = Представление;
		КонецЕсли;
		Если Использование <> Неопределено Тогда
			Элемент.Использование = Использование;
		КонецЕсли;
		Если ВидСравнения <> Неопределено Тогда
			Элемент.ВидСравнения = ВидСравнения;
		КонецЕсли;
		Если ПравоеЗначение <> Неопределено Тогда
			Элемент.ПравоеЗначение = ПравоеЗначение;
		КонецЕсли;
		Если РежимОтображения <> Неопределено Тогда
			Элемент.РежимОтображения = РежимОтображения;
		КонецЕсли;
		Если ИдентификаторПользовательскойНастройки <> Неопределено Тогда
			Элемент.ИдентификаторПользовательскойНастройки = ИдентификаторПользовательскойНастройки;
		КонецЕсли;
	КонецЦикла;

	Возврат МассивЭлементов.Количество();

КонецФункции

// Удалить элементы отбора с заданным именем поля или представлением.
//
// Параметры:
//  ОбластьУдаления - КоллекцияЭлементовОтбораКомпоновкиДанных - контейнер с элементами и группами отбора,
//                                                               например, Список.Отбор или группа в отборе..
//  ИмяПоля         - Строка - имя поля компоновки (не используется для групп).
//  Представление   - Строка - представление поля компоновки.
//
Процедура УдалитьЭлементыГруппыОтбора(Знач ОбластьУдаления, Знач ИмяПоля = Неопределено,
	Знач Представление = Неопределено) Экспорт

	Если ЗначениеЗаполнено(ИмяПоля) Тогда
		ЗначениеПоиска = Новый ПолеКомпоновкиДанных(ИмяПоля);
		СпособПоиска = 1;
	Иначе
		СпособПоиска = 2;
		ЗначениеПоиска = Представление;
	КонецЕсли;

	МассивЭлементов = Новый Массив;

	НайтиРекурсивно(ОбластьУдаления.Элементы, МассивЭлементов, СпособПоиска, ЗначениеПоиска);

	Для Каждого Элемент Из МассивЭлементов Цикл
		Если Элемент.Родитель = Неопределено Тогда
			ОбластьУдаления.Элементы.Удалить(Элемент);
		Иначе
			Элемент.Родитель.Элементы.Удалить(Элемент);
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

// Добавить или заменить существующий элемент отбора.
//
// Параметры:
//  ОбластьПоискаДобавления - КоллекцияЭлементовОтбораКомпоновкиДанных - контейнер с элементами и группами отбора,
//                                     например, Список.Отбор или группа в отборе.
//  ИмяПоля                 - Строка - имя поля компоновки данных (заполняется всегда).
//  ПравоеЗначение          - произвольный - сравниваемое значение.
//  ВидСравнения            - ВидСравненияКомпоновкиДанных - вид сравнения.
//  Представление           - Строка - представление элемента компоновки данных.
//  Использование           - Булево - использование элемента.
//  РежимОтображения        - РежимОтображенияЭлементаНастройкиКомпоновкиДанных - режим отображения.
//  ИдентификаторПользовательскойНастройки - Строка - см. ОтборКомпоновкиДанных.ИдентификаторПользовательскойНастройки
//                                                    в синтакс-помощнике.
//
Процедура УстановитьЭлементОтбора(ОбластьПоискаДобавления, Знач ИмяПоля, Знач ПравоеЗначение = Неопределено,
	Знач ВидСравнения = Неопределено, Знач Представление = Неопределено, Знач Использование = Неопределено,
	Знач РежимОтображения = Неопределено, Знач ИдентификаторПользовательскойНастройки = Неопределено) Экспорт

	ЧислоИзмененных = ИзменитьЭлементыОтбора(ОбластьПоискаДобавления, ИмяПоля, Представление, ПравоеЗначение,
		ВидСравнения, Использование, РежимОтображения, ИдентификаторПользовательскойНастройки);

	Если ЧислоИзмененных = 0 Тогда
		Если ВидСравнения = Неопределено Тогда
			Если ТипЗнч(ПравоеЗначение) = Тип("Массив") Или ТипЗнч(ПравоеЗначение) = Тип("ФиксированныйМассив")
				Или ТипЗнч(ПравоеЗначение) = Тип("СписокЗначений") Тогда
				ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
			Иначе
				ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
			КонецЕсли;
		КонецЕсли;
		Если РежимОтображения = Неопределено Тогда
			РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
		КонецЕсли;
		ДобавитьЭлементКомпоновки(ОбластьПоискаДобавления, ИмяПоля, ВидСравнения, ПравоеЗначение, Представление,
			Использование, РежимОтображения, ИдентификаторПользовательскойНастройки);
	КонецЕсли;

КонецПроцедуры

// Добавить или заменить существующий элемент отбора динамического списка.
//
// Параметры:
//   ДинамическийСписок - ДинамическийСписок - список, в котором требуется установить отбор.
//   ИмяПоля            - Строка - поле, по которому необходимо установить отбор.
//   ПравоеЗначение     - Произвольный - значение отбора.
//       Необязательный. Значение по умолчанию Неопределено.
//       Внимание! Если передать Неопределено, то значение не будет изменено.
//   ВидСравнения  - ВидСравненияКомпоновкиДанных - условие отбора.
//   Представление - Строка - представление элемента компоновки данных.
//       Необязательный. Значение по умолчанию Неопределено.
//       Если указано, то выводится только флажок использования с указанным представлением (значение не выводится).
//       Для очистки (чтобы значение снова выводилось) следует передать пустую строку.
//   Использование - Булево - флажок использования этого отбора.
//       Необязательный. Значение по умолчанию: Неопределено.
//   РежимОтображения - РежимОтображенияЭлементаНастройкиКомпоновкиДанных - способ отображения этого отбора
//                                                                          пользователю.
//       * РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ - В группе быстрых настроек над списком.
//       * РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный       - В настройка списка (в подменю Еще).
//       * РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный   - Запретить пользователю менять этот отбор.
//   ИдентификаторПользовательскойНастройки - Строка - Уникальный идентификатор этого отбора.
//       Используется для связи с пользовательскими настройками.
//
Процедура УстановитьЭлементОтбораДинамическогоСписка(ДинамическийСписок, ИмяПоля, ПравоеЗначение = Неопределено,
	ВидСравнения = Неопределено, Представление = Неопределено, Использование = Неопределено,
	РежимОтображения = Неопределено, ИдентификаторПользовательскойНастройки = Неопределено) Экспорт

	Если РежимОтображения = Неопределено Тогда
		РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
	КонецЕсли;

	Если РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный Тогда
		ОтборДинамическогоСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки.Отбор;
	Иначе
		ОтборДинамическогоСписка = ДинамическийСписок.КомпоновщикНастроек.Настройки.Отбор;
	КонецЕсли;

	УстановитьЭлементОтбора(ОтборДинамическогоСписка, ИмяПоля, ПравоеЗначение, ВидСравнения, Представление,
		Использование, РежимОтображения, ИдентификаторПользовательскойНастройки);

КонецПроцедуры

// Удалить элемент группы отбора динамического списка.
//
// Параметры:
//  ДинамическийСписок - ДинамическийСписок - реквизит формы, для которого требуется установить отбор.
//  ИмяПоля         - Строка - имя поля компоновки (не используется для групп).
//  Представление   - Строка - представление поля компоновки.
//
Процедура УдалитьЭлементыГруппыОтбораДинамическогоСписка(ДинамическийСписок, ИмяПоля = Неопределено,
	Представление = Неопределено) Экспорт

	УдалитьЭлементыГруппыОтбора(ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки.Отбор, ИмяПоля,
		Представление);

	УдалитьЭлементыГруппыОтбора(ДинамическийСписок.КомпоновщикНастроек.Настройки.Отбор, ИмяПоля, Представление);

КонецПроцедуры

// Установить или обновить значение параметра ИмяПараметра динамического списка Список.
//
// Параметры:
//  Список          - ДинамическийСписок - реквизит формы, для которого требуется установить параметр.
//  ИмяПараметра    - Строка             - имя параметра динамического списка.
//  Значение        - Произвольный        - новое значение параметра.
//  Использование   - Булево             - признак использования параметра.
//
Процедура УстановитьПараметрДинамическогоСписка(Список, ИмяПараметра, Значение, Использование = Истина) Экспорт

	ЗначениеПараметраКомпоновкиДанных = Список.Параметры.НайтиЗначениеПараметра(
		Новый ПараметрКомпоновкиДанных(ИмяПараметра));
	Если ЗначениеПараметраКомпоновкиДанных <> Неопределено Тогда
		Если Использование И ЗначениеПараметраКомпоновкиДанных.Значение <> Значение Тогда
			ЗначениеПараметраКомпоновкиДанных.Значение = Значение;
		КонецЕсли;
		Если ЗначениеПараметраКомпоновкиДанных.Использование <> Использование Тогда
			ЗначениеПараметраКомпоновкиДанных.Использование = Использование;
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

Функция УстановитьЗначениеПараметраСКД(КомпоновщикНастроек, ИмяПараметра, ЗначениеПараметра,
	ИспользоватьНеЗаполненный = Истина) Экспорт

	ПараметрУстановлен = Ложь;

	ПараметрКомпоновкиДанных = Новый ПараметрКомпоновкиДанных(ИмяПараметра);
	ЗначениеПараметраКомпоновкиДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
		ПараметрКомпоновкиДанных);
	Если ЗначениеПараметраКомпоновкиДанных <> Неопределено Тогда

		ЗначениеПараметраКомпоновкиДанных.Значение = ЗначениеПараметра;
		ЗначениеПараметраКомпоновкиДанных.Использование = ?(ИспользоватьНеЗаполненный, Истина, ЗначениеЗаполнено(
			ЗначениеПараметраКомпоновкиДанных.Значение));

		ПараметрУстановлен = Истина;

	КонецЕсли;

	Возврат ПараметрУстановлен;

КонецФункции

Процедура НайтиРекурсивно(КоллекцияЭлементов, МассивЭлементов, СпособПоиска, ЗначениеПоиска)

	Для Каждого ЭлементОтбора Из КоллекцияЭлементов Цикл

		Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда

			Если СпособПоиска = 1 Тогда
				Если ЭлементОтбора.ЛевоеЗначение = ЗначениеПоиска Тогда
					МассивЭлементов.Добавить(ЭлементОтбора);
				КонецЕсли;
			ИначеЕсли СпособПоиска = 2 Тогда
				Если ЭлементОтбора.Представление = ЗначениеПоиска Тогда
					МассивЭлементов.Добавить(ЭлементОтбора);
				КонецЕсли;
			КонецЕсли;
		Иначе

			НайтиРекурсивно(ЭлементОтбора.Элементы, МассивЭлементов, СпособПоиска, ЗначениеПоиска);

			Если СпособПоиска = 2 И ЭлементОтбора.Представление = ЗначениеПоиска Тогда
				МассивЭлементов.Добавить(ЭлементОтбора);
			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

КонецПроцедуры

// Выполняет поиск элемента отбора в коллекции по заданному представлению.
//
// Параметры:
//  КоллекцияЭлементов - КоллекцияЭлементовОтбораКомпоновкиДанных - контейнер с элементами и группами отбора,
//                                                                  например, Список.Отбор.Элементы или группа в отборе.
//  Представление - Строка - представление группы.
// 
// Возвращаемое значение:
//  ЭлементОтбораКомпоновкиДанных - элемент отбора.
//
Функция НайтиЭлементОтбораПоПредставлению(КоллекцияЭлементов, Представление) Экспорт

	ВозвращаемоеЗначение = Неопределено;

	Для Каждого ЭлементОтбора Из КоллекцияЭлементов Цикл
		Если ЭлементОтбора.Представление = Представление Тогда
			ВозвращаемоеЗначение = ЭлементОтбора;
			Прервать;
		КонецЕсли;
	КонецЦикла;

	Возврат ВозвращаемоеЗначение
КонецФункции

Процедура СкопироватьЭлементы(ПриемникЗначения, ИсточникЗначения, ОчищатьПриемник = Истина) Экспорт

	Если ТипЗнч(ИсточникЗначения) = Тип("УсловноеОформлениеКомпоновкиДанных") Или ТипЗнч(ИсточникЗначения) = Тип(
		"ВариантыПользовательскогоПоляВыборКомпоновкиДанных") Или ТипЗнч(ИсточникЗначения) = Тип(
		"ОформляемыеПоляКомпоновкиДанных") Или ТипЗнч(ИсточникЗначения) = Тип(
		"ЗначенияПараметровДанныхКомпоновкиДанных") Тогда
		СоздаватьПоТипу = Ложь;
	Иначе
		СоздаватьПоТипу = Истина;
	КонецЕсли;
	ПриемникЭлементов = ПриемникЗначения.Элементы;
	ИсточникЭлементов = ИсточникЗначения.Элементы;
	Если ОчищатьПриемник Тогда
		ПриемникЭлементов.Очистить();
	КонецЕсли;

	Для Каждого ЭлементИсточник Из ИсточникЭлементов Цикл

		Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
			// Элементы порядка добавляем в начало
			Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник);
			ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник));
		Иначе
			Если СоздаватьПоТипу Тогда
				ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник));
			Иначе
				//@skip-check not-enough-parameters
				ЭлементПриемник = ПриемникЭлементов.Добавить();
			КонецЕсли;
		КонецЕсли;

		ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
		// В некоторых коллекциях необходимо заполнить другие коллекции
		Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
			СкопироватьЭлементы(ЭлементПриемник.Поля, ЭлементИсточник.Поля);
			СкопироватьЭлементы(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
			ЗаполнитьЭлементы(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление);
		ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда
			СкопироватьЭлементы(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
		КонецЕсли;
		
		// В некоторых элементах коллекции необходимо заполнить другие коллекции
		Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
			СкопироватьЭлементы(ЭлементПриемник, ЭлементИсточник);
		ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
			СкопироватьЭлементы(ЭлементПриемник, ЭлементИсточник);
		ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда
			СкопироватьЭлементы(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты);
		ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
			ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей());
			ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей());
			ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(
				ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ());
			ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(
				ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ());
		КонецЕсли;

	КонецЦикла;

КонецПроцедуры
Процедура ЗаполнитьЭлементы(ПриемникЗначения, ИсточникЗначения, ПервыйУровень = Неопределено) Экспорт

	Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда
		КоллекцияЗначений = ИсточникЗначения;
	Иначе
		КоллекцияЗначений = ИсточникЗначения.Элементы;
	КонецЕсли;

	Для Каждого ЭлементИсточник Из КоллекцияЗначений Цикл
		Если ПервыйУровень = Неопределено Тогда
			ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
		Иначе
			ЭлементПриемник = ПервыйУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
		КонецЕсли;
		Если ЭлементПриемник = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
		Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
			Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда
				ЗаполнитьЭлементы(ЭлементПриемник.ЗначенияВложенныхПараметров,
					ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры


// Копирует настройки компоновки данных
//
// Параметры:
//	НастройкиПриемник	- НастройкиКомпоновкиДанных, НастройкиВложенногоОбъектаКомпоновкиДанных
//		ГруппировкаКомпоновкиДанных, ГруппировкаТаблицыКомпоновкиДанных, ГруппировкаДиаграммыКомпоновкиДанных,
//		ТаблицаКомпоновкиДанных, ДиаграммаКомпоновкиДанных - коллекция настроек КД, куда копируются настройки
//	НастройкиИсточник	- НастройкиКомпоновкиДанных, НастройкиВложенногоОбъектаКомпоновкиДанных
//		ГруппировкаКомпоновкиДанных, ГруппировкаТаблицыКомпоновкиДанных, ГруппировкаДиаграммыКомпоновкиДанных,
//		ТаблицаКомпоновкиДанных, ДиаграммаКомпоновкиДанных - коллекция настроек КД, откуда копируются настройки.
//
Процедура СкопироватьНастройкиКомпоновкиДанных(НастройкиПриемник, НастройкиИсточник) Экспорт
	
	Если НастройкиИсточник = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(НастройкиПриемник) = Тип("НастройкиКомпоновкиДанных") Тогда
		Для каждого Параметр Из НастройкиИсточник.ПараметрыДанных.Элементы Цикл
			ЗначениеПараметра = НастройкиПриемник.ПараметрыДанных.НайтиЗначениеПараметра(Параметр.Параметр);
			Если ЗначениеПараметра <> Неопределено Тогда
				ЗаполнитьЗначенияСвойств(ЗначениеПараметра, Параметр);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если ТипЗнч(НастройкиИсточник) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ЗаполнитьЗначенияСвойств(НастройкиПриемник, НастройкиИсточник);
		СкопироватьНастройкиКомпоновкиДанных(НастройкиПриемник.Настройки, НастройкиИсточник.Настройки);
		Возврат;
	КонецЕсли;
	
	// Копирование настроек
	Если ТипЗнч(НастройкиИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда
		
		СкопироватьЭлементы(НастройкиПриемник.ПараметрыДанных,		НастройкиИсточник.ПараметрыДанных);
		СкопироватьЭлементы(НастройкиПриемник.ПользовательскиеПоля,	НастройкиИсточник.ПользовательскиеПоля);
		СкопироватьЭлементы(НастройкиПриемник.Отбор,				НастройкиИсточник.Отбор);
		СкопироватьЭлементы(НастройкиПриемник.Порядок,				НастройкиИсточник.Порядок);
		
	КонецЕсли;
	
	Если ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаКомпоновкиДанных")
	 ИЛИ ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаТаблицыКомпоновкиДанных")
	 ИЛИ ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
		
		СкопироватьЭлементы(НастройкиПриемник.ПоляГруппировки,	НастройкиИсточник.ПоляГруппировки);
		СкопироватьЭлементы(НастройкиПриемник.Отбор,			НастройкиИсточник.Отбор);
		СкопироватьЭлементы(НастройкиПриемник.Порядок,			НастройкиИсточник.Порядок);
		ЗаполнитьЗначенияСвойств(НастройкиПриемник,				НастройкиИсточник);
		
	КонецЕсли;
	
	СкопироватьЭлементы(НастройкиПриемник.Выбор,				НастройкиИсточник.Выбор);
	СкопироватьЭлементы(НастройкиПриемник.УсловноеОформление,	НастройкиИсточник.УсловноеОформление);
	ЗаполнитьЭлементы(НастройкиПриемник.ПараметрыВывода,		НастройкиИсточник.ПараметрыВывода);
	
	// Копирование структуры
	Если ТипЗнч(НастройкиИсточник) = Тип("НастройкиКомпоновкиДанных")
	 ИЛИ ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаКомпоновкиДанных") Тогда
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Структура Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Структура.Добавить(ТипЗнч(ЭлементСтруктурыИсточник));
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
	КонецЕсли;
	
	Если ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаТаблицыКомпоновкиДанных")
	 ИЛИ ТипЗнч(НастройкиИсточник) = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Структура Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Структура.Добавить();
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
	КонецЕсли;
	
	Если ТипЗнч(НастройкиИсточник) = Тип("ТаблицаКомпоновкиДанных") Тогда
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Строки Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Строки.Добавить();
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Колонки Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Колонки.Добавить();
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
	КонецЕсли;
	
	Если ТипЗнч(НастройкиИсточник) = Тип("ДиаграммаКомпоновкиДанных") Тогда
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Серии Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Серии.Добавить();
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
		Для каждого ЭлементСтруктурыИсточник Из НастройкиИсточник.Точки Цикл
			ЭлементСтруктурыПриемник = НастройкиПриемник.Точки.Добавить();
			СкопироватьНастройкиКомпоновкиДанных(ЭлементСтруктурыПриемник, ЭлементСтруктурыИсточник);
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры



#КонецОбласти

#Область Отладка

Функция СериализоватьЗапросДляОтладки(ОбъектОтладки)
	СтруктураОбъекта = Новый Структура;

	СтруктураОбъекта.Вставить("Текст", ОбъектОтладки.Текст);

	СтруктураОбъекта.Вставить("Параметры", СкопироватьРекурсивно(ОбъектОтладки.Параметры));

	Если ОбъектОтладки.МенеджерВременныхТаблиц <> Неопределено Тогда
		СтруктураВременныхТаблиц = УИ_ОбщегоНазначенияВызовСервера.СтруктураВременныхТаблицМенеджераВременныхТаблиц(
			ОбъектОтладки.МенеджерВременныхТаблиц);
		СтруктураОбъекта.Вставить("ВременныеТаблицы", СтруктураВременныхТаблиц);
	КонецЕсли;

	Возврат СтруктураОбъекта;
КонецФункции

Функция СериализоватьМенеджерВременныхТаблицДляОтладки(ОбъектОтладки)
	СтруктураОбъекта = Новый Структура;

	СтруктураОбъекта.Вставить("Текст", "");
	СтруктураОбъекта.Вставить("Параметры", Новый Структура);
	СтруктураВременныхТаблиц = УИ_ОбщегоНазначенияВызовСервера.СтруктураВременныхТаблицМенеджераВременныхТаблиц(ОбъектОтладки);
	СтруктураОбъекта.Вставить("ВременныеТаблицы", СтруктураВременныхТаблиц);

	Возврат СтруктураОбъекта;
КонецФункции

Функция СериализоватьСКДДляОтладки(СКД, НастройкиСКД, ВнешниеНаборыДанных)
	Возврат УИ_ОбщегоНазначенияВызовСервера.СериализоватьОбъектСКДДляОтладки(СКД, НастройкиСКД, ВнешниеНаборыДанных);
КонецФункции

Функция СериализоватьОбъектБДДляОтладки(ОбъектОтладки)
	СтруктураОбъекта = Новый Структура;
	СтруктураОбъекта.Вставить("Объект", ОбъектОтладки);

	Возврат СтруктураОбъекта;
КонецФункции

// Сериализовать HTTPЗапрос для отладки.
// 
// Параметры:
//  ЗапросHTTP - HTTPЗапрос -  Запрос HTTP
//  СоединениеHTTP - HTTPСоединение -  Соединение HTTP
// 
// Возвращаемое значение:
//  Структура -  Сериализовать HTTPЗапрос для отладки:
// * Версия - Число - 
// * АдресСервера - Строка - 
// * Порт - Число - 
// * ИспользоватьHTPPS - Булево - 
// * Протокол - Строка - 
// * СоединениеИспользоватьАутентификациюОС - HTTPСоединение, НастройкиКомпоновкиДанных, Неопределено - 
// * ПроксиСервер - Строка - 
// * ПроксиПорт - Число - 
// * ПроксиПользователь - Строка - 
// * ПроксиПароль - Строка - 
// * ИспользоватьАутентификациюОС - Булево - 
// * Запрос - Строка - 
// * ТелоЗапроса - Строка, Неопределено - 
// * Заголовки - Строка - 
// * ДвоичныеДанныеТела - ДвоичныеДанные, Неопределено - 
// * ДвоичныеДанныеТелаСтрокой - Строка - 
// * ИмяФайлаЗапроса - Строка, Неопределено - 
Функция СериализоватьHTTPЗапросДляОтладки(ЗапросHTTP, СоединениеHTTP)
	СтруктураОбъекта = Новый Структура;
	СтруктураОбъекта.Вставить("Версия", 1);
	СтруктураОбъекта.Вставить("АдресСервера", СоединениеHTTP.Сервер);
	СтруктураОбъекта.Вставить("Порт", СоединениеHTTP.Порт);
	СтруктураОбъекта.Вставить("ИспользоватьHTPPS", СоединениеHTTP.ЗащищенноеСоединение <> Неопределено);
	Если СоединениеHTTP.ЗащищенноеСоединение = Неопределено Тогда
		СтруктураОбъекта.Вставить("Протокол", "http");
	Иначе
		СтруктураОбъекта.Вставить("Протокол", "https");
	КонецЕсли;
	
	Если ВерсияПлатформыНеМладше("8.3.7") Тогда
		СтруктураОбъекта.Вставить("СоединениеИспользоватьАутентификациюОС", СоединениеHTTP.ИспользоватьАутентификациюОС);
	КонецЕсли;

	СтруктураОбъекта.Вставить("ПроксиСервер", СоединениеHTTP.Прокси.Сервер(СтруктураОбъекта.Протокол));
	СтруктураОбъекта.Вставить("ПроксиПорт", СоединениеHTTP.Прокси.Порт(СтруктураОбъекта.Протокол));
	СтруктураОбъекта.Вставить("ПроксиПользователь", СоединениеHTTP.Прокси.Пользователь(СтруктураОбъекта.Протокол));
	СтруктураОбъекта.Вставить("ПроксиПароль", СоединениеHTTP.Прокси.Пароль(СтруктураОбъекта.Протокол));
	СтруктураОбъекта.Вставить("ИспользоватьАутентификациюОС", СоединениеHTTP.Прокси.ИспользоватьАутентификациюОС(
		СтруктураОбъекта.Протокол));

	СтруктураОбъекта.Вставить("Запрос", ЗапросHTTP.АдресРесурса);
	СтруктураОбъекта.Вставить("ТелоЗапроса", ЗапросHTTP.ПолучитьТелоКакСтроку());
	СтруктураОбъекта.Вставить("Заголовки", УИ_ОбщегоНазначенияКлиентСервер.ПолучитьСтрокуЗаголовковHTTP(
		ЗапросHTTP.Заголовки));

	ДвоичныеДанныеТела = ЗапросHTTP.ПолучитьТелоКакДвоичныеДанные();
	СтруктураОбъекта.Вставить("ДвоичныеДанныеТела", ДвоичныеДанныеТела);
	СтруктураОбъекта.Вставить("ДвоичныеДанныеТелаСтрокой", Строка(ДвоичныеДанныеТела));

	СтруктураОбъекта.Вставить("ИмяФайлаЗапроса", ЗапросHTTP.ПолучитьИмяФайлаТела());

	Возврат СтруктураОбъекта;

КонецФункции

Функция СериализоватьОбъектДляОтладкиВСтруктуру(ОбъектОтладки, НастройкиСКДИлиСоединениеHTTP, ВнешниеНаборыДанных)
	ТипВсеСсылки = УИ_ОбщегоНазначенияПовтИсп.ОписаниеТипаВсеСсылки();

	СтруктураОбъекта = Новый Структура;
	Если ТипВсеСсылки.СодержитТип(ТипЗнч(ОбъектОтладки)) Тогда
		СтруктураОбъекта = СериализоватьОбъектБДДляОтладки(ОбъектОтладки);
	ИначеЕсли ТипЗнч(ОбъектОтладки) = Тип("HTTPЗапрос") Тогда
		СтруктураОбъекта = СериализоватьHTTPЗапросДляОтладки(ОбъектОтладки, НастройкиСКДИлиСоединениеHTTP);
	ИначеЕсли ТипЗнч(ОбъектОтладки) = Тип("Запрос") Тогда
		СтруктураОбъекта = СериализоватьЗапросДляОтладки(ОбъектОтладки);
	ИначеЕсли ТипЗнч(ОбъектОтладки) = Тип("СхемаКомпоновкиДанных") Тогда
		СтруктураОбъекта = СериализоватьСКДДляОтладки(ОбъектОтладки, НастройкиСКДИлиСоединениеHTTP, ВнешниеНаборыДанных);
	ИначеЕсли ТипЗнч(ОбъектОтладки) = Тип("ТаблицаФормы") Тогда 
		Если Не ЭтоКонтекстСервера() Тогда
			Возврат Неопределено;
		КонецЕсли;
		СКД = ОбъектОтладки.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
		НастройкиСКД = ОбъектОтладки.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
		СтруктураОбъекта = СериализоватьСКДДляОтладки(СКД, НастройкиСКД, Неопределено);
	ИначеЕсли ТипЗнч(ОбъектОтладки) = Тип("МенеджерВременныхТаблиц") Тогда 
		СтруктураОбъекта = СериализоватьМенеджерВременныхТаблицДляОтладки(ОбъектОтладки);
	КонецЕсли;

	Возврат СтруктураОбъекта;
КонецФункции

// Отладить объект.
// 
// Параметры:
// 	ОбъектДляОтладки - Запрос, СхемаКомпоновкиДанных, HTTPЗапрос, ЛюбаяСсылка, ТаблицаФормы - Объект типа Запрос
// 	НастройкиСКДИлиСоединениеHTTP - HTTPСоединение, НастройкиКомпоновкиДанных -
// 	ВнешниеНаборыДанных - Структура Из КлючИЗначение:
// 		* Ключ - Строка -
// 		* ЗНачение - ТаблицаЗначений -
// 	СохранитьВФайл - Булево - Признак сохранения данных отладки в файл на сервере, а не в базу	
// 	Наименование - Строка - Имя сохраненного объекта отладки
// 
// Возвращаемое значение:
//  Неопределено, Строка - Отладить объект
Функция ОтладитьОбъект(ОбъектДляОтладки, НастройкиСКДИлиСоединениеHTTP = Неопределено,
	ВнешниеНаборыДанных = Неопределено, СохранитьВФайл, Наименование = "") Экспорт
	ОткрыватьСразуКонсоль = Ложь;

#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
	ОткрыватьСразуКонсоль = Истина;
#КонецЕсли

	ТипВсеСсылки = УИ_ОбщегоНазначенияПовтИсп.ОписаниеТипаВсеСсылки();
	СериализованныйОбъект = СериализоватьОбъектДляОтладкиВСтруктуру(ОбъектДляОтладки, НастройкиСКДИлиСоединениеHTTP, ВнешниеНаборыДанных);
	Если ТипВсеСсылки.СодержитТип(ТипЗнч(ОбъектДляОтладки)) Тогда
		ТипОбъектаОтладки = "ОбъектБазыДанных";
	ИначеЕсли ТипЗнч(ОбъектДляОтладки) = Тип("HTTPЗапрос") Тогда
		ТипОбъектаОтладки = "HTTPЗапрос";
	ИначеЕсли ТипЗнч(ОбъектДляОтладки) = Тип("Запрос") Тогда
		ТипОбъектаОтладки = "ЗАПРОС";
	ИначеЕсли ТипЗнч(ОбъектДляОтладки) = Тип("МенеджерВременныхТаблиц") Тогда 
		ТипОбъектаОтладки = "МенеджерВременныхТаблиц";
	ИначеЕсли ТипЗнч(ОбъектДляОтладки) = Тип("СхемаКомпоновкиДанных") Тогда
		ТипОбъектаОтладки = "СхемаКомпоновкиДанных";
	ИначеЕсли ТипЗнч(ОбъектДляОтладки) = Тип("ТаблицаФормы") Тогда
		ТипОбъектаОтладки = "СхемаКомпоновкиДанных";
	КонецЕсли;

	Если ОткрыватьСразуКонсоль Тогда
		ДанныеДляОтладки = ПоместитьВоВременноеХранилище(СериализованныйОбъект);
#Если Клиент Тогда

		УИ_ОбщегоНазначенияКлиент.ОткрытьКонсольОтладки(ТипОбъектаОтладки, ДанныеДляОтладки);

#КонецЕсли
		Возврат Неопределено;

	ИначеЕсли СохранитьВФайл Тогда
		Возврат УИ_ОбщегоНазначенияВызовСервера.ЗаписатьДанныеДляОтладкиВФайл(ТипОбъектаОтладки,
																			  СериализованныйОбъект,
																			  Наименование);
	Иначе
		Возврат УИ_ОбщегоНазначенияВызовСервера.ЗаписатьДанныеДляОтладкиВСправочник(ТипОбъектаОтладки,
																					СериализованныйОбъект,
																					Наименование);
	КонецЕсли;
КонецФункции

Функция КлючДанныхОбъектаДанныхОтладкиВХранилищеНастроек() Экспорт
	Возврат "УИ_УниверсальныеИнструменты_ДанныеДляОтладки";
КонецФункции

Функция КлючОбъектаВХранилищеНастроек() Экспорт
	Возврат "УИ_УниверсальныеИнструменты";
КонецФункции

#КонецОбласти

#Область HTTPЗапросы

Функция ЗаголовкиHTTPЗапросаИзСтроки(СтрокаЗаголовков) Экспорт
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст(СтрокаЗаголовков);

	Заголовки = Новый Соответствие;

	Для НомерСтроки = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
		ЗаголовокСтр = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);

		Если Не ЗначениеЗаполнено(ЗаголовокСтр) Тогда
			Продолжить;
		КонецЕсли;

		МассивЗаголовка = СтрРазделить(ЗаголовокСтр, ":");
		Если МассивЗаголовка.Количество() <> 2 Тогда
			Продолжить;
		КонецЕсли;

		Заголовки.Вставить(МассивЗаголовка[0], МассивЗаголовка[1]);

	КонецЦикла;

	Возврат Заголовки;
КонецФункции

Функция ПолучитьСтрокуЗаголовковHTTP(Заголовки) Экспорт
	СтрокаЗаголовков = "";

	Для Каждого КлючЗначение Из Заголовки Цикл
		СтрокаЗаголовков = СтрокаЗаголовков
						   + ?(ЗначениеЗаполнено(СтрокаЗаголовков), Символы.ПС, "")
						   + КлючЗначение.Ключ
						   + ":"
						   + КлючЗначение.Значение;
	КонецЦикла;

	Возврат СтрокаЗаголовков;
КонецФункции

#КонецОбласти

#Область РаботаСJSON

Функция мПрочитатьJSON(Значение, ПрочитатьВСоответствие = Ложь) Экспорт
#Если ВебКлиент Тогда
	Возврат УИ_ОбщегоНазначенияВызовСервера.мПрочитатьJSON(Значение);
#Иначе
		ЧтениеJSON = Новый ЧтениеJSON;
		ЧтениеJSON.УстановитьСтроку(Значение);

		ДанныеДокументаJSON =ПрочитатьJSON(ЧтениеJSON,ПрочитатьВСоответствие);
		ЧтениеJSON.Закрыть();

		Возврат ДанныеДокументаJSON;
#КонецЕсли
КонецФункции // ПрочитатьJSON()

Функция мЗаписатьJSON(СтруктураДанных) Экспорт
#Если ВебКлиент Тогда
	Возврат УИ_ОбщегоНазначенияВызовСервера.мЗаписатьJSON(СтруктураДанных);
#Иначе

		ЗаписьJSON = Новый ЗаписьJSON;
		ЗаписьJSON.УстановитьСтроку();
		ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
		СериализованнаяСтрока = ЗаписьJSON.Закрыть();
		Возврат СериализованнаяСтрока;
#КонецЕсли

КонецФункции // ЗаписатьJSON(

Функция мПрочитатьJSONИзФайла(ИмяФайла, КодировкаФайла = "UTF8") Экспорт
#Если Не ВебКлиент Тогда
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.ОткрытьФайл(ИмяФайла, КодировкаФайла);

	Данные = ПрочитатьJSON(ЧтениеJSON);
	ЧтениеJSON.Закрыть();

	Возврат Данные;
#КонецЕсли

	Возврат Неопределено;
КонецФункции

Процедура мЗаписатьJSONВФайл(ИмяФайла, СтруктураДанных, КодировкаФайла = "UTF8") Экспорт
#Если Не ВебКлиент Тогда
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.ОткрытьФайл(ИмяФайла, КодировкаФайла);
	ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
	ЗаписьJSON.Закрыть();
#КонецЕсли
КонецПроцедуры

#КонецОбласти

#Область НедопустимыеСимволы
// Возвращает строку недопустимых символов.
// Согласно http://en.wikipedia.org/wiki/Filename - в разделе "Reserved characters and words".
// Возвращаемое значение:
//   Строка - строка недопустимых символов.
//
Функция ПолучитьНедопустимыеСимволыВИмениФайла() Экспорт

	НедопустимыеСимволы = """/\[]:;|=?*<>";
	НедопустимыеСимволы = НедопустимыеСимволы + Символы.Таб + Символы.ПС;
	Возврат НедопустимыеСимволы;

КонецФункции

// Проверяет наличие недопустимых символов в имени файла.
//
// Параметры:
//  ИмяФайла  - Строка - имя файла.
//
// Возвращаемое значение:
//   Массив   - массив обнаруженных в имени файла недопустимых символов.
//              Если недопустимых символов не обнаружено - возвращается пустой массив.
//
Функция НайтиНедопустимыеСимволыВИмениФайла(ИмяФайла) Экспорт

	НедопустимыеСимволы = ПолучитьНедопустимыеСимволыВИмениФайла();
	
	МассивНайденныхНедопустимыхСимволов = Новый Массив;
	
	Для ПозицияСимвола = 1 По СтрДлина(НедопустимыеСимволы) Цикл
		ПроверяемыйСимвол = Сред(НедопустимыеСимволы,ПозицияСимвола,1);
		Если СтрНайти(ИмяФайла,ПроверяемыйСимвол) <> 0 Тогда
			МассивНайденныхНедопустимыхСимволов.Добавить(ПроверяемыйСимвол);
		КонецЕсли;
	КонецЦикла;
	
	Возврат МассивНайденныхНедопустимыхСимволов;

КонецФункции

// Заменяет недопустимые символы в имени файла.
//
// Параметры:
//  ИмяФайла     - Строка - исходное имя файла.
//  НаЧтоМенять  - Строка - строка, на которую необходимо заменить недопустимые символы.
//
// Возвращаемое значение:
//   Строка - преобразованное имя файла.
//
Функция ЗаменитьНедопустимыеСимволыВИмениФайла(Знач ИмяФайла, НаЧтоМенять = " ") Экспорт
	
	Возврат СокрЛП(СтрСоединить(СтрРазделить(ИмяФайла, ПолучитьНедопустимыеСимволыВИмениФайла(), Истина), НаЧтоМенять));

КонецФункции


#КонецОбласти

#Область СравнениеВерсий

// Версия платформы не младше 8 3 14.
// 
// Возвращаемое значение:
//  Булево -  Версия платформы не младше 8 3 14
Функция ВерсияПлатформыНеМладше_8_3_14() Экспорт
	Возврат ВерсияПлатформыНеМладше("8.3.14");
КонецФункции

// Версия платформы не младше.
// 
// Параметры:
//  ВерсияДляСравнения - Строка -  Версия для сравнения
// 
// Возвращаемое значение:
//  Булево -  Версия платформы не младше
Функция ВерсияПлатформыНеМладше(ВерсияДляСравнения) Экспорт
	ВерсияБезСборки=ВерсияКонфигурацииБезНомераСборки(ТекущаяВерсияПлатформы1СПредприятие());

	Возврат СравнитьВерсииБезНомераСборки(ВерсияБезСборки, ВерсияДляСравнения)>=0;
КонецФункции

// Получает номер версии конфигурации без номера сборки.
//
// Параметры:
//  Версия - Строка - версия конфигурации в формате РР.ПП.ЗЗ.СС,
//                    где СС - номер сборки, который будет удален.
// 
// Возвращаемое значение:
//  Строка - номер версии конфигурации без номера сборки в формате РР.ПП.ЗЗ.
//
Функция ВерсияКонфигурацииБезНомераСборки(Знач Версия) Экспорт

	Массив = СтрРазделить(Версия, ".");

	Если Массив.Количество() < 3 Тогда
		Возврат Версия;
	КонецЕсли;

	Результат = "[Редакция].[Подредакция].[Релиз]";
	Результат = СтрЗаменить(Результат, "[Редакция]", Массив[0]);
	Результат = СтрЗаменить(Результат, "[Подредакция]", Массив[1]);
	Результат = СтрЗаменить(Результат, "[Релиз]", Массив[2]);

	Возврат Результат;
КонецФункции

// Сравнить две строки версий.
//
// Параметры:
//  СтрокаВерсии1  - Строка - номер версии в формате РР.{П|ПП}.ЗЗ.СС.
//  СтрокаВерсии2  - Строка - второй сравниваемый номер версии.
//
// Возвращаемое значение:
//   Число   - больше 0, если СтрокаВерсии1 > СтрокаВерсии2; 0, если версии равны.
//
Функция СравнитьВерсии(Знач СтрокаВерсии1, Знач СтрокаВерсии2) Экспорт

	Строка1 = ?(ПустаяСтрока(СтрокаВерсии1), "0.0.0.0", СтрокаВерсии1);
	Строка2 = ?(ПустаяСтрока(СтрокаВерсии2), "0.0.0.0", СтрокаВерсии2);
	Версия1 = СтрРазделить(Строка1, ".");
	Если Версия1.Количество() <> 4 Тогда
		ВызватьИсключение СтрШаблон(НСтр("ru = 'Неправильный формат параметра СтрокаВерсии1: %1'"), СтрокаВерсии1);
	КонецЕсли;
	Версия2 = СтрРазделить(Строка2, ".");
	Если Версия2.Количество() <> 4 Тогда
		ВызватьИсключение СтрШаблон(НСтр("ru = 'Неправильный формат параметра СтрокаВерсии2: %1'"), СтрокаВерсии2);
	КонецЕсли;

	Результат = 0;
	Для Разряд = 0 По 3 Цикл
		Результат = Число(Версия1[Разряд]) - Число(Версия2[Разряд]);
		Если Результат <> 0 Тогда
			Возврат Результат;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;

КонецФункции

// Сравнить две строки версий.
//
// Параметры:
//  СтрокаВерсии1  - Строка - номер версии в формате РР.{П|ПП}.ЗЗ.
//  СтрокаВерсии2  - Строка - второй сравниваемый номер версии.
//
// Возвращаемое значение:
//   Число   - больше 0, если СтрокаВерсии1 > СтрокаВерсии2; 0, если версии равны.
//
Функция СравнитьВерсииБезНомераСборки(Знач СтрокаВерсии1, Знач СтрокаВерсии2) Экспорт

	Строка1 = ?(ПустаяСтрока(СтрокаВерсии1), "0.0.0", СтрокаВерсии1);
	Строка2 = ?(ПустаяСтрока(СтрокаВерсии2), "0.0.0", СтрокаВерсии2);
	Версия1 = СтрРазделить(Строка1, ".");
	Если Версия1.Количество() <> 3 Тогда
		ВызватьИсключение СтрШаблон(НСтр("ru = 'Неправильный формат параметра СтрокаВерсии1: %1'"), СтрокаВерсии1);
	КонецЕсли;
	Версия2 = СтрРазделить(Строка2, ".");
	Если Версия2.Количество() <> 3 Тогда
		ВызватьИсключение СтрШаблон(НСтр("ru = 'Неправильный формат параметра СтрокаВерсии2: %1'"), СтрокаВерсии2);
	КонецЕсли;

	Результат = 0;
	Для Разряд = 0 По 2 Цикл
		Результат = Число(Версия1[Разряд]) - Число(Версия2[Разряд]);
		Если Результат <> 0 Тогда
			Возврат Результат;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;

КонецФункции



#КонецОбласти

#Область ПараметрыЗаписи

Функция СтруктураПараметровЗаписиПоУмолчанию() Экспорт
	ПараметрыЗаписи=Новый Структура;
	ПараметрыЗаписи.Вставить("БезАвторегистрацииИзменений", Ложь);
	ПараметрыЗаписи.Вставить("ЗаписьВРежимеЗагрузки", Ложь);
	ПараметрыЗаписи.Вставить("ПривилегированныйРежим", Ложь);
	ПараметрыЗаписи.Вставить("ИспользоватьДопСвойства", Ложь);
	ПараметрыЗаписи.Вставить("ДополнительныеСвойства", Новый Структура);
	ПараметрыЗаписи.Вставить("ИспользоватьПроцедуруПередЗаписью", Ложь);
	ПараметрыЗаписи.Вставить("ПроцедураПередЗаписью", "");

	Возврат ПараметрыЗаписи;
КонецФункции

Функция ПараметрыЗаписиДляВыводаНаФормуИнструмента() Экспорт
	Массив=Новый Массив;
	Массив.Добавить("ЗаписьВРежимеЗагрузки");
	Массив.Добавить("ПривилегированныйРежим");
	Массив.Добавить("БезАвторегистрацииИзменений");

	Возврат Массив;
КонецФункции

Функция ПараметрыЗаписиФормы(Форма, ПрефиксРеквизитаФормы = "ПараметрЗаписи_") Экспорт
	ПараметрыЗаписи=СтруктураПараметровЗаписиПоУмолчанию();

	Для Каждого КлючЗначение Из ПараметрыЗаписи Цикл
		Если ТипЗнч(КлючЗначение.Значение) = Тип("Структура") Тогда
			Для Каждого Стр Из Форма[ПрефиксРеквизитаФормы + КлючЗначение.Ключ] Цикл
				ПараметрыЗаписи[КлючЗначение.Ключ].Вставить(Стр.Ключ, Стр.Значение);
			КонецЦикла;
		Иначе
			ПараметрыЗаписи[КлючЗначение.Ключ]=Форма[ПрефиксРеквизитаФормы + КлючЗначение.Ключ];
		КонецЕсли;
	КонецЦикла;
//	ЗаполнитьЗначенияСвойств(ПараметрыЗаписи, Форма);

	Возврат ПараметрыЗаписи;
КонецФункции

Процедура УстановитьПараметрыЗаписиНаФорму(Форма, ПараметрыЗаписи, ПрефиксРеквизитаФормы = "ПараметрЗаписи_") Экспорт
	Для Каждого КлючЗначение Из ПараметрыЗаписи Цикл
		Если ТипЗнч(КлючЗначение.Значение) = Тип("Структура") Тогда
			Для Каждого КЗ Из КлючЗначение.Значение Цикл
				НС=Форма[ПрефиксРеквизитаФормы + КлючЗначение.Ключ].Добавить();
				НС.Ключ=КЗ.Ключ;
				НС.Значение=КЗ.Значение;
			КонецЦикла;
		Иначе
			Форма[ПрефиксРеквизитаФормы + КлючЗначение.Ключ]=КлючЗначение.Значение;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

#КонецОбласти

#Область СКД

#КонецОбласти

#Область ФайловыеФункции

// Объединяет компоненты файлового пути, с учетом разделителей, принятых в данной ОС. 
// При этом корректно, без дублирования, обрабатываются уже существующие разделители пути.
// 
// Параметры:
//  Путь1 - Строка - Первая часть пути
//  Путь2 - Строка - Вторая часть пути
//  Путь3 - Строка, Неопределено - Третья часть пути
//  Путь4 - Строка, Неопределено - Четвертая часть пути
// 
// Возвращаемое значение:
//  Строка - Объединенный путь.
Функция ОбъединитьПути(Путь1, Путь2, Путь3 = Неопределено, Путь4 = Неопределено) Экспорт
	Разделитель = ПолучитьРазделительПути();
	
	МассивПути = Новый Массив;
	Если СтрЗаканчиваетсяНа(Путь1, Разделитель) Тогда
		МассивПути.Добавить(Лев(Путь1, СтрДлина(Путь1)-1));
	Иначе
		МассивПути.Добавить(Путь1);
	КонецЕсли;
	
	ДопПути = Новый Массив;
	ДопПути.Добавить(Путь2);
	Если ЗначениеЗаполнено(Путь3) Тогда
		ДопПути.Добавить(Путь3);
	КонецЕсли;
	Если ЗначениеЗаполнено(Путь4) Тогда
		ДопПути.Добавить(Путь4);
	КонецЕсли;
	
	Для Каждого ТекПуть Из ДопПути Цикл
		ПутьДляФинальногоПути = ТекПуть;
		Если СтрНачинаетсяС(ПутьДляФинальногоПути, Разделитель) Тогда
			ПутьДляФинальногоПути=Сред(ПутьДляФинальногоПути, 2);
		КонецЕсли;

		Если СтрЗаканчиваетсяНа(ПутьДляФинальногоПути, Разделитель) Тогда
			МассивПути.Добавить(Лев(ПутьДляФинальногоПути, СтрДлина(ПутьДляФинальногоПути) - 1));
		Иначе
			МассивПути.Добавить(ПутьДляФинальногоПути);
		КонецЕсли;
	КонецЦикла;
	
	Возврат СтрСоединить(МассивПути, Разделитель);
	
КонецФункции

// Каталог вспомогательных библиотек инструментов.
// 
// Параметры:
//  РабочийКаталогПользователя - Строка - Каталог, в котором будет распологаться вспомогательные данные инструментов
// 
// Возвращаемое значение:
//  Строка - Каталог вспомогательных библиотек инструментов
Функция КаталогВспомогательныхБиблиотекИнструментов(РабочийКаталогПользователя) Экспорт
	Возврат ОбъединитьПути(РабочийКаталогПользователя, "tools_ui_1c", Формат(Версия(), "ЧГ=0;"))
КонецФункции

// Случайное имя файла.
// 
// Параметры:
//  Расширение - Строка - Расширение
//  Префикс - Строка - Префикс
// 
// Возвращаемое значение:
//  Строка - Случайное имя файла
Функция СлучайноеИмяФайла(Расширение = "tmp", Префикс = "") Экспорт
	Возврат Префикс
//			+ Формат(СлучайноеЧисло, "ЧГ=0;")
			+ Формат(ТекущаяУниверсальнаяДатаВМиллисекундах(), "ЧГ=0;")
			+ "."
			+ Расширение;
КонецФункции

// Получить индекс пиктограммы файла.
// 
// Параметры:
//  РасширениеФайла - Строка -Расширение файла
// 
// Возвращаемое значение:
//  Число -  Получить индекс пиктограммы файла
Функция ПолучитьИндексПиктограммыФайла(Знач РасширениеФайла) Экспорт

	Если ТипЗнч(РасширениеФайла) <> Тип("Строка") Или ПустаяСтрока(РасширениеФайла) Тогда

		Возврат 0;
	КонецЕсли;

	РасширениеФайла = РасширениеБезТочки(РасширениеФайла);

	Расширение = "." + НРег(РасширениеФайла) + ";";

	Если СтрНайти(".dt;.1cd;.cf;.cfu;", Расширение) <> 0 Тогда
		Возврат 6; // Файлы 1С.

	ИначеЕсли Расширение = ".mxl;" Тогда
		Возврат 8; // Табличный Файл.

	ИначеЕсли СтрНайти(".txt;.log;.ini;", Расширение) <> 0 Тогда
		Возврат 10; // Текстовый Файл.

	ИначеЕсли Расширение = ".epf;" Тогда
		Возврат 12; // Внешние обработки.

	ИначеЕсли СтрНайти(".ico;.wmf;.emf;", Расширение) <> 0 Тогда
		Возврат 14; // Картинки.

	ИначеЕсли СтрНайти(".htm;.html;.url;.mht;.mhtml;", Расширение) <> 0 Тогда
		Возврат 16; // HTML.

	ИначеЕсли СтрНайти(".doc;.dot;.rtf;", Расширение) <> 0 Тогда
		Возврат 18; // Файл Microsoft Word.

	ИначеЕсли СтрНайти(".xls;.xlw;", Расширение) <> 0 Тогда
		Возврат 20; // Файл Microsoft Excel.

	ИначеЕсли СтрНайти(".ppt;.pps;", Расширение) <> 0 Тогда
		Возврат 22; // Файл Microsoft PowerPoint.

	ИначеЕсли СтрНайти(".vsd;", Расширение) <> 0 Тогда
		Возврат 24; // Файл Microsoft Visio.

	ИначеЕсли СтрНайти(".mpp;", Расширение) <> 0 Тогда
		Возврат 26; // Файл Microsoft Visio.

	ИначеЕсли СтрНайти(".mdb;.adp;.mda;.mde;.ade;", Расширение) <> 0 Тогда
		Возврат 28; // База данных Microsoft Access.

	ИначеЕсли СтрНайти(".xml;", Расширение) <> 0 Тогда
		Возврат 30; // xml.

	ИначеЕсли СтрНайти(".msg;", Расширение) <> 0 Тогда
		Возврат 32; // Письмо электронной почты.

	ИначеЕсли СтрНайти(".zip;.rar;.arj;.cab;.lzh;.ace;", Расширение) <> 0 Тогда
		Возврат 34; // Архивы.

	ИначеЕсли СтрНайти(".exe;.com;.bat;.cmd;", Расширение) <> 0 Тогда
		Возврат 36; // Исполняемые файлы.

	ИначеЕсли СтрНайти(".grs;", Расширение) <> 0 Тогда
		Возврат 38; // Графическая схема.

	ИначеЕсли СтрНайти(".geo;", Расширение) <> 0 Тогда
		Возврат 40; // Географическая схема.

	ИначеЕсли СтрНайти(".jpg;.jpeg;.jp2;.jpe;", Расширение) <> 0 Тогда
		Возврат 42; // jpg.

	ИначеЕсли СтрНайти(".bmp;.dib;", Расширение) <> 0 Тогда
		Возврат 44; // bmp.

	ИначеЕсли СтрНайти(".tif;.tiff;", Расширение) <> 0 Тогда
		Возврат 46; // tif.

	ИначеЕсли СтрНайти(".gif;", Расширение) <> 0 Тогда
		Возврат 48; // gif.

	ИначеЕсли СтрНайти(".png;", Расширение) <> 0 Тогда
		Возврат 50; // png.

	ИначеЕсли СтрНайти(".pdf;", Расширение) <> 0 Тогда
		Возврат 52; // pdf.

	ИначеЕсли СтрНайти(".odt;", Расширение) <> 0 Тогда
		Возврат 54; // Open Office writer.

	ИначеЕсли СтрНайти(".odf;", Расширение) <> 0 Тогда
		Возврат 56; // Open Office math.

	ИначеЕсли СтрНайти(".odp;", Расширение) <> 0 Тогда
		Возврат 58; // Open Office Impress.

	ИначеЕсли СтрНайти(".odg;", Расширение) <> 0 Тогда
		Возврат 60; // Open Office draw.

	ИначеЕсли СтрНайти(".ods;", Расширение) <> 0 Тогда
		Возврат 62; // Open Office calc.

	ИначеЕсли СтрНайти(".mp3;", Расширение) <> 0 Тогда
		Возврат 64;

	ИначеЕсли СтрНайти(".erf;", Расширение) <> 0 Тогда
		Возврат 66; // Внешние отчеты.

	ИначеЕсли СтрНайти(".docx;", Расширение) <> 0 Тогда
		Возврат 68; // Файл Microsoft Word docx.

	ИначеЕсли СтрНайти(".xlsx;", Расширение) <> 0 Тогда
		Возврат 70; // Файл Microsoft Excel xlsx.

	ИначеЕсли СтрНайти(".pptx;", Расширение) <> 0 Тогда
		Возврат 72; // Файл Microsoft PowerPoint pptx.

	ИначеЕсли СтрНайти(".p7s;", Расширение) <> 0 Тогда
		Возврат 74; // Файл подписи.

	ИначеЕсли СтрНайти(".p7m;", Расширение) <> 0 Тогда
		Возврат 76; // зашифрованное сообщение.
	Иначе
		Возврат 4;
	КонецЕсли;

КонецФункции

// Преобразует расширение файла в нижний регистр без точки.
//
// Параметры:
//  Расширение - Строка - Расширение для преобразования.
//
// Возвращаемое значение:
//  Строка.
//
Функция РасширениеБезТочки(Знач Расширение) Экспорт

	Расширение = НРег(СокрЛП(Расширение));

	Если Сред(Расширение, 1, 1) = "." Тогда
		Расширение = Сред(Расширение, 2);
	КонецЕсли;

	Возврат Расширение;

КонецФункции

#КонецОбласти

#Область НастройкиИнструментов

Функция ИмяСохраненнойНастройкиКаталогаИнструментовНаСервере() Экспорт
	Возврат "УИ_КаталогДанныхИнструментовНаСервере";
КонецФункции

Функция КлючДанныхНастроекВХранилищеНастроек() Экспорт
	Возврат "УИ_УниверсальныеИнструменты_Настройки";
КонецФункции

Функция КлючНастроекПараметровСеанса() Экспорт
	Возврат "ПараметрыСеанса";
КонецФункции

#КонецОбласти

#Область ПараметрыПоставки

Функция ИмяФайлаСкачивания() Экспорт
	Возврат "UI.cfe";
КонецФункции

Функция ВариантПоставки() Экспорт
	Возврат "Расширение";
КонецФункции

Функция ВариантПоставкиПортативный() Экспорт
	Возврат "Портативный";
КонецФункции

Функция Версия() Экспорт
	Возврат "1.4.6";	
КонецФункции

Функция ЭтоПортативнаяПоставка() Экспорт
	Возврат ВариантПоставки() = ВариантПоставкиПортативный();	
КонецФункции

#КонецОбласти

#Область РаботаСТипами

// Представление типов.
// 
// Параметры:
//  ОжидаемыеТипы - ОписаниеТипов, Тип, Массив из Тип-  Ожидаемые типы
// 
// Возвращаемое значение:
//  Строка -  Представление типов
Функция ПредставлениеТипов(ОжидаемыеТипы) Экспорт
	Если ТипЗнч(ОжидаемыеТипы) = Тип("Массив") Тогда
		Результат = "";
		Индекс = 0;
		Для Каждого Тип Из ОжидаемыеТипы Цикл
			Если Не ПустаяСтрока(Результат) Тогда
				Результат = Результат + ", ";
			КонецЕсли;
			Результат = Результат + ПредставлениеТипа(Тип);
			Индекс = Индекс + 1;
			Если Индекс > 10 Тогда
				Результат = Результат + ",... " + СтрШаблон(НСтр("ru='(всего %1 типов)'"), ОжидаемыеТипы.Количество());
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Возврат Результат;
	Иначе
		Возврат ПредставлениеТипа(ОжидаемыеТипы);
	КонецЕсли;
КонецФункции

// Представление типа.
// 
// Параметры:
//  Тип - Произвольный, Тип, ОписаниеТипов -  Тип
// 
// Возвращаемое значение:
//  Строка -  Представление типа
Функция ПредставлениеТипа(Тип) Экспорт
	Если Тип = Неопределено Тогда
		Возврат "Неопределено";
	ИначеЕсли ТипЗнч(Тип) = Тип("ОписаниеТипов") Тогда
		ТипСтрокой = Строка(Тип);
		Возврат ?(СтрДлина(ТипСтрокой) > 150, Лев(ТипСтрокой, 150) + "..." + СтрШаблон(НСтр("ru='(всего %1 типов)'"),
			Тип.Типы().Количество()), ТипСтрокой);
	Иначе
		ТипСтрокой = Строка(Тип);
		Возврат ?(СтрДлина(ТипСтрокой) > 150, Лев(ТипСтрокой, 150) + "...", ТипСтрокой);
	КонецЕсли;
КонецФункции

// Значение ожидаемого типа.
// 
// Параметры:
//  Значение - Неопределено, Произвольный -  Значение
//  ОжидаемыеТипы - ОписаниеТипов, Тип, Массив из Тип, Произвольный -  Ожидаемые типы
// 
// Возвращаемое значение:
//  Булево, Неопределено -  Значение ожидаемого типа
Функция ЗначениеОжидаемогоТипа(Значение, ОжидаемыеТипы) Экспорт
	ТипЗначения = ТипЗнч(Значение);
	Если ТипЗнч(ОжидаемыеТипы) = Тип("ОписаниеТипов") Тогда
		Возврат ОжидаемыеТипы.Типы().Найти(ТипЗначения) <> Неопределено;
	ИначеЕсли ТипЗнч(ОжидаемыеТипы) = Тип("Тип") Тогда
		Возврат ТипЗначения = ОжидаемыеТипы;
	ИначеЕсли ТипЗнч(ОжидаемыеТипы) = Тип("Массив") Или ТипЗнч(ОжидаемыеТипы) = Тип("ФиксированныйМассив") Тогда
		Возврат ОжидаемыеТипы.Найти(ТипЗначения) <> Неопределено;
	ИначеЕсли ТипЗнч(ОжидаемыеТипы) = Тип("Соответствие") Или ТипЗнч(ОжидаемыеТипы) = Тип("ФиксированноеСоответствие") Тогда
		Возврат ОжидаемыеТипы.Получить(ТипЗначения) <> Неопределено;
	КонецЕсли;
	Возврат Неопределено;
КонецФункции

// Создает объект ОписаниеТипов, содержащий тип Строка.
//
// Параметры:
//  ДлинаСтроки - Число - длина строки.
//
// Возвращаемое значение:
//  ОписаниеТипов - описание типа Строка.
//
Функция ОписаниеТипаСтрока(ДлинаСтроки) Экспорт

	Массив = Новый Массив;
	Массив.Добавить(Тип("Строка"));

	КвалификаторСтроки = Новый КвалификаторыСтроки(ДлинаСтроки, ДопустимаяДлина.Переменная);

	Возврат Новый ОписаниеТипов(Массив, , КвалификаторСтроки);

КонецФункции

// Создает объект ОписаниеТипов, содержащий тип Число.
//
// Параметры:
//  Разрядность - Число - общее количество разрядов числа (количество разрядов
//                        целой части плюс количество разрядов дробной части).
//  РазрядностьДробнойЧасти - Число - число разрядов дробной части.
//  ЗнакЧисла - ДопустимыйЗнак - допустимый знак числа.
//
// Возвращаемое значение:
//  ОписаниеТипов - описание типа Число.
Функция ОписаниеТипаЧисло(Разрядность, РазрядностьДробнойЧасти = 0, ЗнакЧисла = Неопределено) Экспорт

	Если ЗнакЧисла = Неопределено Тогда
		КвалификаторЧисла = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти);
	Иначе
		КвалификаторЧисла = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, ЗнакЧисла);
	КонецЕсли;

	Возврат Новый ОписаниеТипов("Число", КвалификаторЧисла);

КонецФункции

// Создает объект ОписаниеТипов, содержащий тип Дата.
//
// Параметры:
//  ЧастиДаты - ЧастиДаты - набор вариантов использования значений типа Дата.
//
// Возвращаемое значение:
//  ОписаниеТипов - описание типа Дата.
Функция ОписаниеТипаДата(ЧастиДаты) Экспорт

	Массив = Новый Массив;
	Массив.Добавить(Тип("Дата"));

	КвалификаторДаты = Новый КвалификаторыДаты(ЧастиДаты);

	Возврат Новый ОписаниеТипов(Массив, , , КвалификаторДаты);

КонецФункции

// Тип таблица значений.
// 
// Возвращаемое значение:
//  Тип -  Тип таблица значений
Функция ТипТаблицаЗначений() Экспорт
	ОписаниеТиповТЗ = Новый ОписаниеТипов("ТаблицаЗначений");
	Возврат ОписаниеТиповТЗ.Типы()[0];
	
КонецФункции

// Тип таблица значений.
// 
// Возвращаемое значение:
//  Тип -  Тип таблица значений
Функция ТипДеревоЗначений() Экспорт
	ОписаниеТиповТЗ = Новый ОписаниеТипов("ДеревоЗначений");
	Возврат ОписаниеТиповТЗ.Типы()[0];
	
КонецФункции

// Идентификатор типа.
// 
// Параметры:
//  Тип - Тип
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа
Функция ИдентификаторТипа(Тип) Экспорт
	Если Тип = Тип("Число") Тогда
		Возврат "Число";
	ИначеЕсли Тип = Тип("Строка") Тогда
		Возврат "Строка";
	ИначеЕсли Тип = Тип("Булево") Тогда
		Возврат "Булево";
	ИначеЕсли Тип = Тип("Дата") Тогда
		Возврат "Дата";
	ИначеЕсли Тип = Тип("Неопределено") Тогда
		Возврат "Неопределено";
	ИначеЕсли Тип = Тип("Null") Тогда
		Возврат "Null";
	ИначеЕсли Тип = Тип("Тип") Тогда
		Возврат "Тип";
	КонецЕсли;

#Если ВебКлиент Тогда
	Возврат УИ_ОбщегоНазначенияВызовСервера.ИдентификаторТипа(Тип);

#Иначе
		ЗаписьXML = Новый ЗаписьXML;
		ЗаписьXML.УстановитьСтроку();
			//@skip-check undefined-variable
		СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Тип, "Type", "http://v8.1c.ru/8.1/data/core");
		СериализованнаяСтрокаТипа = ЗаписьXML.Закрыть();

		ТекИмя = "";
		ИдентификаторТипа = "";

		ЧтениеXML = Новый ЧтениеXML;
		ЧтениеXML.УстановитьСтроку(СериализованнаяСтрокаТипа);
		Пока ЧтениеXML.Прочитать() Цикл
			Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
				ТекИмя = ЧтениеXML.Имя;
			ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст И ТекИмя = "Type" Тогда
				ИдентификаторТипа = ЧтениеXML.Значение;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		ЧтениеXML.Закрыть();

//		Возврат СтрЗаменить(ИдентификаторТипа, ":", "_");

		ЧастиИдентификатора = СтрРазделить(ИдентификаторТипа, ":");
		ИдентификаторДляВозврата =  ЧастиИдентификатора[ЧастиИдентификатора.Количество() - 1];
		Если СтрНайти(ИдентификаторДляВозврата, ".") > 0 Тогда
			Если СтрНайти(ИдентификаторДляВозврата, "TabularSection.") > 0 Тогда
				ИдентификаторДляВозврата = "TabularSection";
			ИначеЕсли СтрНайти(ИдентификаторДляВозврата, "TabularSectionRow.") > 0 Тогда 
				ИдентификаторДляВозврата = "TabularSectionRow";
			КонецЕсли;
		КонецЕсли;
		
		Возврат ИдентификаторДляВозврата;
//
//		Возврат ИдентификаторТипа;
#КонецЕсли

КонецФункции

// Тип доступен в контексте.
// 
// Параметры:
//  ОписаниеТипа - см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеТипаПлатформы
//  ВидКонтекста - Строка
// 
// Возвращаемое значение:
//  Булево - Тип доступен в контексте
Функция ТипДоступенВКонтексте(ОписаниеТипа, ВидКонтекста) Экспорт
	Если ОписаниеТипа = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(ОписаниеТипа.Доступность) Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат СтрНайти(ОписаниеТипа.Доступность, ВРег(ВидКонтекста))>0;	
КонецФункции

// Тип доступен на сервере.
// 
// Параметры:
//  ОписаниеТипа - см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеТипаПлатформы
// 
// Возвращаемое значение:
//  Булево - Тип доступен на сервере
Функция ТипДоступенНаСервере(ОписаниеТипа) Экспорт
	ВидыКонтектса = ДоступныеКонтекстыПлатформы();
	Возврат  ТипДоступенВКонтексте(ОписаниеТипа, ВидыКонтектса.Сервер);
КонецФункции

// Это примитивный тип.
// 
// Параметры:
//  Тип -  Тип
// 
// Возвращаемое значение:
//  Булево
Функция ЭтоПримитивныйТип(Тип) Экспорт
	Возврат Тип = Тип("Число")
			Или Тип = Тип("Строка")
			Или Тип = Тип("Дата")
			Или Тип = Тип("Неопределено")
			Или Тип = Тип("Булево")
			Или Тип = Тип("null");
КонецФункции

// Идентификатор типа любая ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа любая ссылка
Функция ИдентификаторТипаЛюбаяСсылка() Экспорт
	Возврат "AnyRef";	
КонецФункции

// Идентификатор типа справочник ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа справочник ссылка
Функция ИдентификаторТипаСправочникСсылка() Экспорт
	Возврат "CatalogRef";	
КонецФункции

// Идентификатор типа документ ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа документ ссылка
Функция ИдентификаторТипаДокументСсылка() Экспорт
	Возврат "DocumentRef";	
КонецФункции

// Идентификатор типа бизнесс процесс ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа бизнесс процесс ссылка
Функция ИдентификаторТипаБизнессПроцессСсылка() Экспорт
	Возврат "BusinessProcessRef";	
КонецФункции

// Идентификатор типа точка маршрута бизнес процесса ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа точка маршрута бизнес процесса ссылка
Функция ИдентификаторТипаТочкаМаршрутаБизнесПроцессаСсылка() Экспорт
	Возврат "BusinessProcessRoutePointRef";	
КонецФункции

// Идентификатор типа план счетов ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа план счетов ссылка
Функция ИдентификаторТипаПланСчетовСсылка() Экспорт
	Возврат "ChartOfAccountsRef";	
КонецФункции

// Идентификатор типа план видов расчета ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа план видов расчета ссылка
Функция ИдентификаторТипаПланВидовРасчетаСсылка() Экспорт
	Возврат "ChartOfCalculationTypesRef";	
КонецФункции

// Идентификатор типа план видов характеристик ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа план видов характеристик ссылка
Функция ИдентификаторТипаПланВидовХарактеристикСсылка() Экспорт
	Возврат "ChartOfCharacteristicTypesRef";	
КонецФункции

// Идентификатор типа перечисление ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа перечисление ссылка
Функция ИдентификаторТипаПеречислениеСсылка() Экспорт
	Возврат "EnumRef";	
КонецФункции

// Идентификатор типа план обмена ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа план обмена ссылка
Функция ИдентификаторТипаПланОбменаСсылка() Экспорт
	Возврат "ExchangePlanRef";	
КонецФункции

// Идентификатор типа задача ссылка.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа задача ссылка
Функция ИдентификаторТипаЗадачаСсылка() Экспорт
	Возврат "TaskRef";	
КонецФункции

// Идентификатор типа характиристика плана видов характеристик.
// 
// Параметры:
//  ИмяПланаВидовХарактеристик - Строка - Имя плана видов характеристик
// 
// Возвращаемое значение:
//  Строка
Функция ИдентификаторТипаХарактиристикаПланаВидовХарактеристик(ИмяПланаВидовХарактеристик) Экспорт
	Возврат ИдентификаторТипаХарактиристика()+"." + ИмяПланаВидовХарактеристик;	
КонецФункции

// Идентификатор типа характиристика.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа характиристика
Функция ИдентификаторТипаХарактиристика() Экспорт
	Возврат "Characteristic";	
КонецФункции

// Идентификатор типа определяемого типа.
// 
// Параметры:
//  ИмяОпределяемогоТипа -Строка- Имя определяемого типа
// 
// Возвращаемое значение:
//  Строка
Функция ИдентификаторТипаОпределяемогоТипа(ИмяОпределяемогоТипа) Экспорт
	Возврат ИдентификаторТипаОпределяемогоТипаБазовый() + "." + ИмяОпределяемогоТипа;
КонецФункции

// Идентификатор типа определяемого типа базовый.
// 
// Возвращаемое значение:
//  Строка - Идентификатор типа определяемого типа базовый
Функция ИдентификаторТипаОпределяемогоТипаБазовый() Экспорт
	Возврат "DefinedType";
КонецФункции

// Коллекция свойств типа с учетом расширения.
// 
// Параметры:
//  Коллекция 	- Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеСвойстваТипа
//  			- Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеЗначенияТипа
//  			- Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеМетодаТипа
//  КлючРасширения - Неопределено, Строка - Ключ расширения
// 
// Возвращаемое значение:
//  - Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеСвойстваТипа
//  - Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеЗначенияТипа
//  - Массив из см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеМетодаТипа
Функция КоллекцияСвойствТипаСУчетомРасширения(Коллекция, КлючРасширения = Неопределено) Экспорт
	Если КлючРасширения = Неопределено Тогда
		Возврат Коллекция;
	КонецЕсли;
	
	НоваяКоллекция = Новый Массив;
	Для Каждого ЭлементКоллекции Из Коллекция Цикл
		УсловияВыполнены = Истина;
		Если ЭлементКоллекции.ЭтоРасширениеТипа И ЭлементКоллекции.КлючРасширенияТипа <> КлючРасширения Тогда
			УсловияВыполнены = Ложь;
		КонецЕсли;

		Если Не УсловияВыполнены Тогда
			Продолжить;
		КонецЕсли;	
		НоваяКоллекция.Добавить(ЭлементКоллекции);	
	КонецЦикла;
	Возврат НоваяКоллекция;
КонецФункции

#Область СборкаОписанияТиповИзСтроки


// Добавить в строке описания типа строку типа.
// 
// Параметры:
//  СтрокаОписанияТипов -Строка -Строка описания типов
//  СтрокаТипа - Строка-Строка типа
Процедура ДобавитьКСериализованнойСтрокеОписанияТипаСтрокуТипа(СтрокаОписанияТипов, СтрокаТипа) Экспорт
	СтрокаОписанияТипов = СтрокаОписанияТипов+"
	|<TypeSet xmlns:d2p1=""http://v8.1c.ru/8.1/data/enterprise/current-config"">d2p1:"+СтрокаТипа+"</TypeSet>";
	
КонецПроцедуры

// Описание типа сериализованная строка заголовок.
// 
// Возвращаемое значение:
//  Строка - Описание типа сериализованная строка заголовок
Функция ОписаниеТипаСериализованнаяСтрокаЗаголовок() Экспорт
	Возврат "<TypeDescription xmlns=""http://v8.1c.ru/8.1/data/core"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">";
КонецФункции

// Описание типа сериализованная строка подвал.
// 
// Возвращаемое значение:
//  Строка - Описание типа сериализованная строка подвал
Функция ОписаниеТипаСериализованнаяСтрокаПодвал() Экспорт
	Возврат "</TypeDescription>";	
КонецФункции

#КонецОбласти

#КонецОбласти

#Область РедакторТипов

// Доступные наборы типов для редактирования.
// 
// Возвращаемое значение:
//  Структура -  Доступные наборы типов для редактирования:
// * Ссылки - Строка - 
// * СоставныеСсылки - Строка - 
// * Примитивные - Строка - 
// * Null - Строка - 
// * ХранилищеЗначения - Строка - 
// * КоллекцииЗначений - Строка - 
// * МоментВремени - Строка - 
// * Тип - Строка - 
// * ОписаниеТипов - Строка - 
// * Граница - Строка - 
// * УникальныйИдентификатор - Строка - 
// * СтандартныйПериод - Строка - 
// * СистемныеПеречисления - Строка - 
// * ТабличныйДокумент - Строка - 
// * Картинка - Строка - 
// * ДвоичныеДанные - Строка - 
// * ФиксированныеКоллекцииЗначений - Строка - 
Функция ДоступныеНаборыТиповДляРедактирования() Экспорт
	ДоступныеНаборы = Новый Структура;
	ДоступныеНаборы.Вставить("Ссылки","ССЫЛКИ");
	ДоступныеНаборы.Вставить("СоставныеСсылки","СОСТАВНЫЕССЫЛКИ");
	ДоступныеНаборы.Вставить("Примитивные","ПРИМИТИВНЫЕ");
	ДоступныеНаборы.Вставить("Null","NULL");
	ДоступныеНаборы.Вставить("ХранилищеЗначения","ХРАНИЛИЩЕЗНАЧЕНИЙ");
	ДоступныеНаборы.Вставить("КоллекцииЗначений","КОЛЛЕКЦИИЗНАЧЕНИЙ");
	ДоступныеНаборы.Вставить("МоментВремени","МОМЕНТВРЕМЕНИ");
	ДоступныеНаборы.Вставить("Тип","ТИП");
	ДоступныеНаборы.Вставить("ОписаниеТипов","ОПИСАНИЕТИПОВ");
	ДоступныеНаборы.Вставить("Граница","ГРАНИЦА");
	ДоступныеНаборы.Вставить("УникальныйИдентификатор","УНИКАЛЬНЫЙИДЕНТИФИКАТОР");
	ДоступныеНаборы.Вставить("СтандартныйПериод","СТАНДАРТНЫЙПЕРИОД");
	ДоступныеНаборы.Вставить("СистемныеПеречисления","СИСТЕМНЫЕПЕРЕЧИСЛЕНИЯ");
	ДоступныеНаборы.Вставить("ТабличныйДокумент","ТАБЛИЧНЫЙДОКУМЕНТ");
	ДоступныеНаборы.Вставить("Картинка","КАРТИНКА");
	ДоступныеНаборы.Вставить("ДвоичныеДанные","ДВОИЧНЫЕДАННЫЕ");
	ДоступныеНаборы.Вставить("ФиксированныеКоллекцииЗначений","ФИКСИРОВАННЫЕКОЛЛЕКЦИИЗНАЧЕНИЙ");
	
	Возврат ДоступныеНаборы;
КонецФункции

// Наборы типов для редактирования по умолчанию для поля формы.
// 
// Возвращаемое значение:
// Массив из  Строка -  Наборы типов для редактирования по умолчанию для поля формы
Функция НаборыТиповДляРедактированияПоУмолчаниюДляПоляФормы() Экспорт
	ДоступныеНаборы = ДоступныеНаборыТиповДляРедактирования();
	
	Наборы = Новый Массив;
	Наборы.Добавить(ДоступныеНаборы.Ссылки);
	Наборы.Добавить(ДоступныеНаборы.Примитивные);
	Наборы.Добавить(ДоступныеНаборы.УникальныйИдентификатор);
	Возврат Наборы;
КонецФункции

// Все наборы типов для редактирования.
// 
// Возвращаемое значение:
// Массив из Строка -  Все наборы типов для редактирования
Функция ВсеНаборыТиповДляРедактирования() Экспорт
	ДоступныеНаборы = ДоступныеНаборыТиповДляРедактирования();
	
	Наборы = Новый Массив;
	
	Для Каждого КлючЗначение Из ДоступныеНаборы Цикл
		Наборы.Добавить(КлючЗначение.Значение);
	КонецЦикла;
	
	Возврат Наборы;
	
КонецФункции

// Хранимые наборы типов для редактирования.
// 
// Возвращаемое значение:
//  Массив из Строка-  Хранимые наборы типов для редактирования
Функция ХранимыеНаборыТиповДляРедактирования() Экспорт
	ДоступныеНаборы = ДоступныеНаборыТиповДляРедактирования();
	
	Наборы = Новый Массив;
	Наборы.Добавить(ДоступныеНаборы.Ссылки);
	Наборы.Добавить(ДоступныеНаборы.СоставныеСсылки);
	Наборы.Добавить(ДоступныеНаборы.Примитивные);
	Наборы.Добавить(ДоступныеНаборы.ХранилищеЗначения);
	Наборы.Добавить(ДоступныеНаборы.УникальныйИдентификатор);
	
	Возврат Наборы;
	
КонецФункции

// Наборы типов для поля схемы компоновки данных.
// 
// Возвращаемое значение:
//  Массив из Строка -  Наборы типов для поля схемы компоновки данных
Функция НаборыТиповДляПоляСхемыКомпоновкиДанных() Экспорт
	ДоступныеНаборы = ДоступныеНаборыТиповДляРедактирования();
	
	Наборы = Новый Массив;
	Наборы.Добавить(ДоступныеНаборы.Ссылки);
	Наборы.Добавить(ДоступныеНаборы.СоставныеСсылки);
	Наборы.Добавить(ДоступныеНаборы.Примитивные);
	Наборы.Добавить(ДоступныеНаборы.ХранилищеЗначения);
	Наборы.Добавить(ДоступныеНаборы.УникальныйИдентификатор);
	Наборы.Добавить(ДоступныеНаборы.Null);
	
	Возврат Наборы;
		
КонецФункции

// Наборы типов для параметров сеансов.
// 
// Возвращаемое значение:
//  Массив Из Строка
Функция НаборыТиповДляПараметровСеансов() Экспорт
	ДоступныеНаборы = ДоступныеНаборыТиповДляРедактирования();
	
	Наборы = Новый Массив;
	Наборы.Добавить(ДоступныеНаборы.Ссылки);
	Наборы.Добавить(ДоступныеНаборы.СоставныеСсылки);
	Наборы.Добавить(ДоступныеНаборы.Примитивные);
	Наборы.Добавить(ДоступныеНаборы.ХранилищеЗначения);
	Наборы.Добавить(ДоступныеНаборы.УникальныйИдентификатор);
	Наборы.Добавить(ДоступныеНаборы.Null);
	Наборы.Добавить(ДоступныеНаборы.ДвоичныеДанные);
	Наборы.Добавить(ДоступныеНаборы.ОписаниеТипов);
	Наборы.Добавить(ДоступныеНаборы.ФиксированныеКоллекцииЗначений);
	Наборы.Добавить(ДоступныеНаборы.СистемныеПеречисления);
	
	Возврат Наборы;
КонецФункции

// Пустой уникальный идентификатор.
// 
// Возвращаемое значение:
//  УникальныйИдентификатор
Функция ПустойУникальныйИдентификатор() Экспорт
	Возврат Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
КонецФункции

// Пустое значение типа.
// 
// Параметры:
//  Тип - Тип, ОписаниеТипов -
//  ХранитьВКонтейнере - Булево
// 
// Возвращаемое значение:
//  Произвольный
Функция ПустоеЗначениеТипа(Тип, ХранитьВКонтейнере = Ложь) Экспорт
	Если ХранитьВКонтейнере Тогда
		Возврат "";
	КонецЕсли;		

	Если ТипЗнч(Тип) = Тип("ОписаниеТипов") Тогда
		ОписаниеТипов = Тип;
	Иначе
		МассивТипов = Новый Массив;
		МассивТипов.Добавить(Тип);
		ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
	КонецЕсли;
		
	Возврат ОписаниеТипов.ПривестиЗначение(Неопределено);
КонецФункции

#КонецОбласти

#Область КонтейнерЗначенияДляХраненияНаФорме

#Область КонтейнерУниверсальныйЗначения

// Виды контейнера универсального значения.
// 
// Возвращаемое значение:
//  Структура - Виды контейнера универсального значения:
// * Значение - Строка - 
// * ХранилищеЗначения - Строка - 
// * ВременноеХранилище - Строка - 
// * СериализованноеЗначение - Строка - 
// * СтруктураВоВременномХранилище - Строка -
// * ОбъектМетаданных - Строка -
Функция ВидыКонтейнераУниверсальногоЗначения() Экспорт
	Виды = Новый Структура;
	Виды.Вставить("Значение", "Значение");
	Виды.Вставить("ХранилищеЗначения", "ХранилищеЗначения");
	Виды.Вставить("ВременноеХранилище", "ВременноеХранилище");
	Виды.Вставить("СериализованноеЗначение", "СериализованноеЗначение");
	Виды.Вставить("СтруктураВоВременномХранилище", "СтруктураВоВременномХранилище");
	Виды.Вставить("ОбъектМетаданных", "ОбъектМетаданных");
	
	Возврат Виды;	
КонецФункции

// Новый хранилище значения универсального значения.
// 
// Возвращаемое значение:
//  Структура - Новый хранилище значения универсального значения:
// * Вид - Строка - 
// * Хранилище - Неопределено - 
// * ОписаниеТипа - Неопределено -
// 				  - см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеТипаПлатформы 
// * ИмяОбъектаМетаданных - Строка - 
// * ИменаСвойствДляДоступаКЗначению - Массив из Строка - 
Функция НовыйХранилищеЗначенияУниверсальногоЗначения() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Вид", "");
	Хранилище.Вставить("Хранилище", Неопределено);
	Хранилище.Вставить("ОписаниеТипа", Неопределено);
	Хранилище.Вставить("ИмяОбъектаМетаданных", "");
	Хранилище.Вставить("ИменаСвойствДляДоступаКЗначению", Новый Массив);	
	
	Возврат Хранилище;
КонецФункции

// Установить значение в элементы формы контейнера универсального значения.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ДанныеФормы - ДанныеФормыСтруктура, ДанныеФормыЭлементДерева, ДанныеФормыЭлементКоллекции -Данные формы
//  Значение - Произвольный -Значение
//  УстановитьЗначениеВКонтейнер - Булево -
Процедура УстановитьЗначениеВЭлементыФормыКонтейнераУниверсальногоЗначения(Форма, ДанныеФормы, Значение,
	УстановитьЗначениеВКонтейнер) Экспорт
	ВидыКонтейнераЗначения = ВидыКонтейнераУниверсальногоЗначения();

	ТипЗначения = ТипЗнч(Значение);

	ЭтоОбъектМетаданных = Ложь;
	ОписаниеТипа = Неопределено;
#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
	Если ТипЗначения = Тип("ОбъектМетаданных") Тогда
		ЭтоОбъектМетаданных = Истина;
		ОписаниеТипа = УИ_ОбщегоНазначения.ОписаниеТипаОбъектаМетаданных(Значение);

		ПолноеИмяОбъектаМетаданных = Значение.ПолноеИмя();
		ДанныеФормы.ИмяОбъектаМетаданных = ПолноеИмяОбъектаМетаданных;
	КонецЕсли;
#КонецЕсли
	Если Не ЭтоОбъектМетаданных Тогда
		ОписаниеТипа = УИ_ТипыПлатформыКлиентСервер.ОписаниеТипаПлатформыПоТипу(ТипЗначения);
	КонецЕсли;
	Попытка
		ДанныеФормы.ЗначениеПредставление = Строка(Значение);
	Исключение
		Если ОписаниеТипа <> Неопределено Тогда
			ДанныеФормы.ЗначениеПредставление = ОписаниеТипа.Имя;
		КонецЕсли;
	КонецПопытки;
	Если ОписаниеТипа = Неопределено Тогда
		ДанныеФормы.ЗначениеЕстьОшибка = Истина;
		ДанныеФормы.ЗначениеОписаниеОшибки = "Не удалось получить описание типа "
											 + ТипЗначения
											 + ". Создайте задачу разработчику с идентификатором типа "
											 + ИдентификаторТипа(ТипЗначения);

		СообщитьПользователю(ДанныеФормы.ЗначениеОписаниеОшибки);
		Возврат;
	КонецЕсли;
	
	ДанныеФормы.ЗначениеТипЗначения = ОписаниеТипа;
	ДанныеФормы.ЗначениеТипЗначенияПредставление = ОписаниеТипа.Имя;
	Если СтрНайти(ОписаниеТипа.Имя, ".<") >0 Тогда
		ЧастиИмени = СтрРазделить(ОписаниеТипа.Имя, ".");
		
		ИдентификаторТипа = ИдентификаторТипа(ТипЗначения);
		ЧастиИдентификатора = СтрРазделить(ИдентификаторТипа, ".");
		ПредставлениеТипа = ИдентификаторТипа;
		Если ЧастиИмени.Количество() = ЧастиИдентификатора.Количество() Тогда
			ЧастиПредставления = Новый Массив;
			Для ИндексЧасти =0  По ЧастиИмени.Количество() -1 Цикл
				Если СтрНайти(ЧастиИмени[ИндексЧасти], "<")>0 Тогда
					ЧастиПредставления.Добавить(ЧастиИдентификатора[ИндексЧасти]);
				Иначе
					ЧастиПредставления.Добавить(ЧастиИмени[ИндексЧасти]);
				КонецЕсли;
			КонецЦикла;
			ПредставлениеТипа = СтрСоединить(ЧастиПредставления, ".");
		КонецЕсли;
		
		ДанныеФормы.ЗначениеТипЗначенияПредставление = ПредставлениеТипа;
	КонецЕсли;
	
	#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
	ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения);
	Если ОбъектМД<> Неопределено Тогда
		ДанныеФормы.ИмяОбъектаМетаданных = ОбъектМД.ПолноеИмя();
	КонецЕсли;
	#КонецЕсли
	
	Если ЭтоОбъектМетаданных Тогда
		ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.ОбъектМетаданных;
		ДанныеФормы.ЗначениеКонтейнер = ДанныеФормы.ИмяОбъектаМетаданных;
		Возврат;
	КонецЕсли;
	ДанныеФормы.ВидКонтейнера = "";
//	ДанныеФормы.Значение = Неопределено;
	Если ЭтоПримитивныйТип(ТипЗначения) Тогда
		ДанныеФормы.ЗначениеКонтейнер = Значение;
		ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.Значение;
	КонецЕсли;

	Если Не УстановитьЗначениеВКонтейнер Тогда
		Возврат;
	КонецЕсли;

//	Если ТипДоступенВКонтексте(ОписаниеТипа, Форма.КонтекстКлиента) И ТипДоступенНаСервере(ОписаниеТипа) Тогда
//		
//		//@skip-check empty-except-statement
//		Попытка
//			ДанныеФормы.Значение = Значение;
//			ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.Значение;
//		Исключение
//		КонецПопытки;
//	КонецЕсли;

#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
	Если Не ЗначениеЗаполнено(ДанныеФормы.ВидКонтейнера) Тогда
		//@skip-check empty-except-statement
		Попытка
			ДанныеФормы.ЗначениеКонтейнер = Новый ХранилищеЗначения(Значение);
			ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.ХранилищеЗначения;
		Исключение
		КонецПопытки;
	КонецЕсли;
#КонецЕсли

	Если Не ЗначениеЗаполнено(ДанныеФормы.ВидКонтейнера) Тогда
		//@skip-check empty-except-statement
		Попытка
			ДанныеФормы.ЗначениеКонтейнер = ПоместитьВоВременноеХранилище(Значение, Форма.УникальныйИдентификатор);
			ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.ВременноеХранилище;
		Исключение
		КонецПопытки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ДанныеФормы.ВидКонтейнера) Тогда
		//@skip-check empty-except-statement
		Попытка
			ДанныеФормы.ЗначениеКонтейнер = УИ_ОбщегоНазначения.ЗначениеВСтрокуXML(Значение);
			ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.СериализованноеЗначение;
		Исключение
		КонецПопытки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ДанныеФормы.ВидКонтейнера) Тогда
		ЗначениеДляКонтейнера = Новый Структура;
		ЗначениеДляКонтейнера.Вставить("Значение", Значение);
		//@skip-check empty-except-statement
		Попытка
			ДанныеФормы.ЗначениеКонтейнер = ПоместитьВоВременноеХранилище(ЗначениеДляКонтейнера, Форма.УникальныйИдентификатор);
			ДанныеФормы.ВидКонтейнера = ВидыКонтейнераЗначения.СтруктураВоВременномХранилище;
		Исключение
		КонецПопытки;
	КонецЕсли;
КонецПроцедуры

// Значение из хранилища контейнера универсального значения.
// 
// Параметры:
//  Хранилище - см. НовыйХранилищеЗначенияУниверсальногоЗначения
// 
// Возвращаемое значение:
//  Произвольный
Функция ЗначениеИзХранилищаКонтейнераУниверсальногоЗначения(Хранилище) Экспорт
	ВидыКонтейнераЗначения = ВидыКонтейнераУниверсальногоЗначения();

	Значение = Неопределено;
	Если Хранилище.Вид = ВидыКонтейнераЗначения.Значение Тогда
		Значение = Хранилище.Хранилище;
	ИначеЕсли Хранилище.Вид = ВидыКонтейнераЗначения.ХранилищеЗначения Тогда
#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
		Значение = Хранилище.Хранилище.Получить();
#КонецЕсли
	ИначеЕсли
	Хранилище.Вид = ВидыКонтейнераЗначения.ВременноеХранилище Тогда
		Значение = ПолучитьИзВременногоХранилища(Хранилище.Хранилище);
	ИначеЕсли Хранилище.Вид = ВидыКонтейнераЗначения.СериализованноеЗначение Тогда
		Значение = УИ_ОбщегоНазначения.ЗначениеИзСтрокиXML(Хранилище.Хранилище);
	ИначеЕсли Хранилище.Вид = ВидыКонтейнераЗначения.СтруктураВоВременномХранилище Тогда
		СтруктураЗначения = ПолучитьИзВременногоХранилища(Хранилище.Хранилище);
		Если ТипЗнч(СтруктураЗначения) = Тип("Структура") Тогда
			Значение = СтруктураЗначения.Значение;
		КонецЕсли;
	ИначеЕсли Хранилище.Вид = ВидыКонтейнераЗначения.ОбъектМетаданных Тогда
#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
		Значение = Метаданные.НайтиПоПолномуИмени(Хранилище.Хранилище);
#КонецЕсли
	КонецЕсли;
	
	Если Хранилище.ИменаСвойствДляДоступаКЗначению.Количество() = 0 Тогда
		Возврат Значение;
	КонецЕсли;
	Если Значение = Неопределено Тогда
		Возврат Значение;
	КонецЕсли;
	
	ИндексСвойства = Хранилище.ИменаСвойствДляДоступаКЗначению.Количество() -1;
	Пока ИндексСвойства>=0 Цикл
		ИмяСвойства = Хранилище.ИменаСвойствДляДоступаКЗначению[ИндексСвойства];
		Значение = Значение[ИмяСвойства];
		
		ИндексСвойства = ИндексСвойства -1;
	КонецЦикла; 
	
	Возврат Значение;
КонецФункции



#КонецОбласти

#Область ХранениеНаФормеДанныхКонтейнера

// Суффикс имени поля хранения типа значения для поля с контейнером.
// 
// Возвращаемое значение:
//  Строка -  Суффикс имени поля хранения типа значения для поля с контейнером
Функция СуффиксИмениПоляХраненияТипаЗначенияДляПоляСКонтейнером() Экспорт
	Возврат "ТипЗначения";
КонецФункции

// Новый структура хранения реквизита на форме с конейнером.
// 
// Параметры:
//  ИмяПоля - Строка- Имя поля
// 
// Возвращаемое значение:
//  Структура - Новый структура хранения реквизита на форме с конейнером:
// * ИмяПоляВСтруктуре - Строка - 
// * ИмяПоляКонтейнера - Строка - 
// * ИмяПоляТипаЗначения - Строка - 
// * ИмяПоляПредставленияТипаЗначения - Строка - 
Функция НовыйСтруктураХраненияРеквизитаНаФормеСКонейнером(ИмяПоля) Экспорт
	СтруктураХраненияРеквизита = Новый Структура;
	СтруктураХраненияРеквизита.Вставить("ИмяПоляВСтруктуре", ИмяПоля);
	СтруктураХраненияРеквизита.Вставить("ИмяПоляКонтейнера", ИмяПоля
															 + СуффиксИмениПоляХраненияКонтейнераДляПоляСКонтейнером());
	СтруктураХраненияРеквизита.Вставить("ИмяПоляТипаЗначения", ИмяПоля
															   + СуффиксИмениПоляХраненияТипаЗначенияДляПоляСКонтейнером());
	СтруктураХраненияРеквизита.Вставить("ИмяПоляПредставленияТипаЗначения", ИмяПоля
																			+ СуффиксИмениПоляХраненияПредставленияТипаЗначенияДляПоляСКонтейнером());

	Возврат СтруктураХраненияРеквизита;
КонецФункции

// Суффикс имени поля хранения представления типа значения для поля с контейнером.
// 
// Возвращаемое значение:
//  Строка -  Суффикс имени поля хранения представления типа значения для поля с контейнером
Функция СуффиксИмениПоляХраненияПредставленияТипаЗначенияДляПоляСКонтейнером() Экспорт
	Возврат "ТипЗначенияПредставление";
КонецФункции

// Суффикс имени поля хранения контейнера для поля с контейнером.
// 
// Возвращаемое значение:
//  Строка -  Суффикс имени поля хранения контейнера для поля с контейнером
Функция СуффиксИмениПоляХраненияКонтейнераДляПоляСКонтейнером() Экспорт
	Возврат "Контейнер";
КонецФункции



#КонецОбласти

#Область ХранилищаКонтейнеров

// Новый хранилище значения типа граница.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа граница:
// * ВидГраницы - Строка - Включая или Исключая
// * Дата - Дата - 
Функция НовыйХранилищеЗначенияТипаГраница() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("ВидГраницы","Включая");
	Хранилище.Вставить("Дата",'00010101');
	
	Возврат Хранилище;	
КонецФункции

// Новый хранилище значения типа момент времени.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа момент времени:
// * Дата - Дата - 
// * Ссылка - Неопределено, ЛюбаяСсылка, ОбсуждениеСистемыВзаимодействия - 
Функция НовыйХранилищеЗначенияТипаМоментВремени() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Дата", '00010101');
	Хранилище.Вставить("Ссылка", Неопределено);

	Возврат Хранилище;
КонецФункции

// Новый хранилище значения таблицы значений.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения таблицы значений:
// * Значение - Строка - 
// * КоличествоСтрок - Число - 
// * КоличествоКолонок - Число - 
Функция НовыйХранилищеЗначенияТаблицыЗначений() Экспорт
	Хранилище=Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("КоличествоСтрок", 0);
	Хранилище.Вставить("КоличествоКолонок", 0);
	Возврат Хранилище;
	
КонецФункции

// Новый хранилище значения дерева значений.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения дерева значений:
// * Значение - Строка - 
// * КоличествоСтрок - Число - 
// * КоличествоКолонок - Число - 
Функция НовыйХранилищеЗначенияДереваЗначений() Экспорт
	Хранилище=Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("КоличествоСтрок", 0);
	Хранилище.Вставить("КоличествоКолонок", 0);
	Возврат Хранилище;
	
КонецФункции

// Новый хранилище значения типа.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа:
// * Значение - Строка - 
// * Имя - Строка - 
Функция НовыйХранилищеЗначенияТипа() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("Имя", "");
	
	Возврат Хранилище;
КонецФункции

// Новый хранилище значения типа структура.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа структура:
// * Значение - Строка - 
// * КоличествоКлючей - Число - 
// * Ключи - Строка - Разделенные запятой ключи структуры
Функция НовыйХранилищеЗначенияТипаСтруктура() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("КоличествоКлючей", 0);
	Хранилище.Вставить("Ключи", "");
	
	Возврат Хранилище;
КонецФункции

// Новый хранилище значения типа структура.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа структура:
// * Значение - Строка - 
// * КоличествоКлючей - Число - 
Функция НовыйХранилищеЗначенияТипаСоответствие() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("КоличествоКлючей", 0);
	
	Возврат Хранилище;
КонецФункции

// Новый хранилище значения типа табличный документ.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа табличный документ:
// * Значение - ТабличныйДокумент - 
// * КоличествоСтрок - Число - 
// * КоличествоКолонок - Число - 
Функция НовыйХранилищеЗначенияТипаТабличныйДокумент() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", Новый ТабличныйДокумент);
	Хранилище.Вставить("КоличествоСтрок", 0);
	Хранилище.Вставить("КоличествоКолонок", 0);
	
	Возврат Хранилище;
КонецФункции

// Новый хранилище значения типа хранилище значения.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа хранилище значения:
// * Значение - Строка - 
// * Тип - Строка - 
Функция НовыйХранилищеЗначенияТипаХранилищеЗначения() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("Тип", "");
	
	Возврат Хранилище;
	
КонецФункции

// Новый хранилище значения типа список значений.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа список значений:
// * Значение - Строка - 
// * Представление - Строка - 
Функция НовыйХранилищеЗначенияТипаСписокЗначений() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("Представление", "");
	
	Возврат Хранилище;
	
КонецФункции

// Новый хранилище значения типа массив.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа массив:
// * Значение - Строка - 
// * Представление - Строка - 
Функция НовыйХранилищеЗначенияТипаМассив() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", "");
	Хранилище.Вставить("Представление", "");
	
	Возврат Хранилище;
	
КонецФункции

// Новый хранилище значения типа картинка.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа картинка:
// * Значение - Картинка - 
// * Вид - Строка - 
Функция НовыйХранилищеЗначенияТипаКартинка() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", Новый Картинка);
	Хранилище.Вставить("Вид", "Пустая");
	
	Возврат Хранилище;
КонецФункции

// Новый хранилище значения типа двоичные данные.
// 
// Возвращаемое значение:
//  Структура -  Новый хранилище значения типа двоичные данные:
// * Значение - Неопределено, ХранилищеЗначения - 
// * Размер - Число - 
// * Представление - Строка - 
Функция НовыйХранилищеЗначенияТипаДвоичныеДанные() Экспорт
	Хранилище = Новый Структура;
	Хранилище.Вставить("Значение", Неопределено);
	Хранилище.Вставить("Размер", 0);
	Хранилище.Вставить("Представление", "");
	
	Возврат Хранилище;
КонецФункции

#КонецОбласти

#Область ХранилищеКонтейнераИзЗначения

// Значение хранилища контейнера момента времени по дате и ссылке.
// 
// Параметры:
//  Дата - Дата -  Дата
//  Ссылка - СсылкаНаОбъектИнформационнойБазыИлиОбсуждениеСистемыВзаимодействия -  Ссылка
// 
// Возвращаемое значение:
//  см. УИ_ОбщегоНазначенияКлиентСервер.НовыйХранилищеЗначенияТипаМоментВремени
Функция ЗначениеХранилищаКонтейнераМоментаВремениПоДатеИСсылке(Дата, Ссылка) Экспорт
	Хранилище = НовыйХранилищеЗначенияТипаМоментВремени();
	Хранилище.Дата = Дата;
	Хранилище.Ссылка = Ссылка;
	Возврат Хранилище;
КонецФункции

// Значение хранилища контейнера границы по дате и виду строкой.
// 
// Параметры:
//  Дата - Дата
//  ВидГраницы - Строка - - Включая или Исключая
// 
// Возвращаемое значение:
//  см. НовыйХранилищеЗначенияТипаГраница
Функция ЗначениеХранилищаКонтейнераГраницыПоДатеИВидуСтрокой(Дата, ВидГраницы) Экспорт
	Хранилище = НовыйХранилищеЗначенияТипаГраница();
	Хранилище.Дата = Дата;
	Хранилище.ВидГраницы = ВидГраницы;
	Возврат Хранилище;
КонецФункции

// Значение хранилище контейнера табличного документа.
// 
// Параметры:
//  ТабДокумент - ТабличныйДокумент- Таб документ
// 
// Возвращаемое значение:
//  см. УИ_ОбщегоНазначенияКлиентСервер.НовыйХранилищеЗначенияТипаТабличныйДокумент 
Функция ЗначениеХранилищеКонтейнераТабличногоДокумента(ТабДокумент) Экспорт
	Хранилище = НовыйХранилищеЗначенияТипаТабличныйДокумент();
	Хранилище.Значение = ТабДокумент;
	Хранилище.КоличествоСтрок= ТабДокумент.ВысотаТаблицы;
	Хранилище.КоличествоКолонок = ТабДокумент.ШиринаТаблицы;
	
	Возврат Хранилище;	
	
КонецФункции

// Значение хранилища контейнера картинки.
// 
// Параметры:
//  Картинка - Картинка
// 
// Возвращаемое значение:
//  см. НовыйХранилищеЗначенияТипаКартинка
Функция ЗначениеХранилищаКонтейнераКартинки(Картинка) Экспорт
	Хранилище = НовыйХранилищеЗначенияТипаКартинка();
	Хранилище.Значение = Картинка;
	Хранилище.Вид = Строка(Картинка.Вид);
	
	Возврат Хранилище;	
	
КонецФункции

// Значение хранилище универсального значения.
// 
// Параметры:
//  Значение - Произвольный - Значение
//  ИдентификаторФормы - УникальныйИдентификатор -  Идентификатор формы
//  ИменаСвойствДляДоступаКЗначению - Массив из Строка, Неопределено -  
// 
// Возвращаемое значение:
//  
// См. НовыйХранилищеЗначенияУниверсальногоЗначения
Функция ЗначениеХранилищеУниверсальногоЗначения(Значение, ИдентификаторФормы,
	ИменаСвойствДляДоступаКЗначению = Неопределено) Экспорт
	ВидыХранилища = ВидыКонтейнераУниверсальногоЗначения();

	Хранилище = НовыйХранилищеЗначенияУниверсальногоЗначения();
	ТипЗначения = ТипЗнч(Значение);
	Хранилище.ОписаниеТипа = УИ_ТипыПлатформыКлиентСервер.ОписаниеТипаПлатформыПоТипу(ТипЗначения);
	Хранилище.ИмяОбъектаМетаданных = УИ_ОбщегоНазначения.ИмяОбъектаМетаданныхТипа(ТипЗначения);

#Если Сервер Тогда
	Если Не ЗначениеЗаполнено(Хранилище.Вид) Тогда
		//@skip-check empty-except-statement
		Попытка
			Хранилище.Хранилище = Новый ХранилищеЗначения(Значение);
			Хранилище.Вид = ВидыХранилища.ХранилищеЗначения;
		Исключение
		КонецПопытки;
	КонецЕсли;
#КонецЕсли

	Если Не ЗначениеЗаполнено(Хранилище.Вид) Тогда
		//@skip-check empty-except-statement
		Попытка
			Хранилище.Хранилище = ПоместитьВоВременноеХранилище(Значение, ИдентификаторФормы);
			Хранилище.Вид= ВидыХранилища.ВременноеХранилище;
		Исключение
		КонецПопытки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Хранилище.Вид) Тогда
		//@skip-check empty-except-statement
		Попытка
			Хранилище.Хранилище = УИ_ОбщегоНазначения.ЗначениеВСтрокуXML(Значение);
			Хранилище.Вид = ВидыХранилища.СериализованноеЗначение;
		Исключение
		КонецПопытки;
	КонецЕсли;

	Если ИменаСвойствДляДоступаКЗначению <> Неопределено Тогда
		Хранилище.ИменаСвойствДляДоступаКЗначению = ИменаСвойствДляДоступаКЗначению;
	КонецЕсли;
	
	Возврат Хранилище;
КонецФункции

#КонецОбласти

#Область ЗначениеИзХранилищаКонтейнера

// Значение из хранилища контейнера соответствия.
// 
// Параметры:
//  Хранилище -см. НовыйХранилищеЗначенияТипаТабличныйДокумент
// 
// Возвращаемое значение:
// ТабличныйДокумент 
Функция ЗначениеИзХранилищаКонтейнераТабличногоДокумента(Хранилище) Экспорт
	Возврат Хранилище.Значение;
КонецФункции

// Значение из хранилища контейнера картинки.
// 
// Параметры:
//  Хранилище - см. НовыйХранилищеЗначенияТипаКартинка
// 
// Возвращаемое значение:
// Картинка 
Функция ЗначениеИзХранилищаКонтейнераКартинки(Хранилище) Экспорт
	Возврат Хранилище.Значение;
КонецФункции

#КонецОбласти
	
// Хранить тип в контейнере.
// 
// Параметры:
//  ТипЗначения -Тип 
// 
// Возвращаемое значение:
//  Булево -  Хранить тип в контейнере
Функция ХранитьТипВКонтейнере(ТипЗначения) Экспорт
	Типы = ТипыЗначенийХранимыеВКонтейнерах();
	Возврат Типы.Найти(ТипЗначения) <> Неопределено;
КонецФункции

// Типы значений хранимые в конрейнерах.
// 
// Возвращаемое значение:
//  Массив из Тип-  Типы значений хранимые в конрейнерах
Функция ТипыЗначенийХранимыеВКонтейнерах() Экспорт
	Возврат ОписаниеТиповХранимыхВКонтейнере().Типы();	
КонецФункции

// Описание типов хранимых к контейнере.
// 
// Возвращаемое значение:
//  ОписаниеТипов -  Описание типов хранимых к контейнере
Функция ОписаниеТиповХранимыхВКонтейнере() Экспорт
	МассивТипов = Новый Массив;
	МассивТипов.Добавить("МоментВремени");
	МассивТипов.Добавить("ТаблицаЗначений");
	МассивТипов.Добавить("ДеревоЗначений");
	МассивТипов.Добавить("Тип");
	МассивТипов.Добавить("ОписаниеТипов");
	МассивТипов.Добавить("Граница");
	МассивТипов.Добавить("ХранилищеЗначения");
	МассивТипов.Добавить("Массив");
	МассивТипов.Добавить("СписокЗначений");
	МассивТипов.Добавить("ТабличныйДокумент");
	МассивТипов.Добавить("Соответствие");
	МассивТипов.Добавить("Структура");
	МассивТипов.Добавить("Картинка");
	МассивТипов.Добавить("ДвоичныеДанные");
	МассивТипов.Добавить("ФиксированнаяСтруктура");
	МассивТипов.Добавить("ФиксированноеСоответствие");
	МассивТипов.Добавить("ФиксированныйМассив");

	Возврат Новый ОписаниеТипов(СтрСоединить(МассивТипов,","));
КонецФункции

// Типы контейнеров значения.
// 
// Возвращаемое значение:
//  Структура -  Типы контейнеров значения:
// * ТаблицаЗначений - Строка - 
// * ДеревоЗначений - Строка - 
// * МоментВремени - Строка - 
// * Тип - Строка - 
// * ОписаниеТипов - Строка - 
// * ХранилищеЗначения - Строка - 
// * Массив - Строка - 
// * СписокЗначений - Строка - 
// * Граница - Строка - 
// * ТабличныйДокумент - Строка - 
// * Соответствие - Строка - 
// * Структура - Строка - 
// * Картинка - Строка - 
// * ДвоичныеДанные - Строка - 
// * ФиксированнаяСтруктура - Строка - 
// * ФиксированноеСоответствие - Строка - 
// * ФиксированныйМассив - Строка - 
// * Универсальный - Строка - 
Функция ТипыКонтейнеровЗначения() Экспорт
	ТипыКонтейнеров = Новый Структура;
	ТипыКонтейнеров.Вставить("ТаблицаЗначений", "ТАБЛИЦАЗНАЧЕНИЙ");
	ТипыКонтейнеров.Вставить("ДеревоЗначений", "ДЕРЕВОЗНАЧЕНИЙ");
	ТипыКонтейнеров.Вставить("МоментВремени", "МОМЕНТВРЕМЕНИ");
	ТипыКонтейнеров.Вставить("Тип", "ТИП");
	ТипыКонтейнеров.Вставить("ОписаниеТипов", "ОПИСАНИЕТИПОВ");
	ТипыКонтейнеров.Вставить("ХранилищеЗначения", "ХРАНИЛИЩЕЗНАЧЕНИЯ");
	ТипыКонтейнеров.Вставить("Массив", "МАССИВ");
	ТипыКонтейнеров.Вставить("СписокЗначений", "СПИСОКЗНАЧЕНИЙ");
	ТипыКонтейнеров.Вставить("Граница", "ГРАНИЦА");
	ТипыКонтейнеров.Вставить("ТабличныйДокумент", "ТАБЛИЧНЫЙДОКУМЕНТ");
	ТипыКонтейнеров.Вставить("Соответствие", "СООТВЕТСТВИЕ");
	ТипыКонтейнеров.Вставить("Структура", "СТРУКТУРА");
	ТипыКонтейнеров.Вставить("Картинка", "КАРТИНКА");
	ТипыКонтейнеров.Вставить("ДвоичныеДанные", "ДВОИЧНЫЕДАННЫЕ");
	ТипыКонтейнеров.Вставить("ФиксированнаяСтруктура", "ФИКСИРОВАННАЯСТРУКТУРА");
	ТипыКонтейнеров.Вставить("ФиксированноеСоответствие", "ФИКСИРОВАННОЕСООТВЕТСТВИЕ");
	ТипыКонтейнеров.Вставить("ФиксированныйМассив", "ФИКСИРОВАННЫЙМАССИВ");
	ТипыКонтейнеров.Вставить("Универсальный", "УНИВЕРСАЛЬНЫЙ");
	
	Возврат ТипыКонтейнеров;
КонецФункции

// Новый контейнер значения.
// 
// Возвращаемое значение:
//  Структура -  Новый контейнер значения:
// * Тип - Строка - доступные типы см. ТипыКонтейнеровЗначения
// * ОписаниеТипа - Неопределено
// 				  - см. УИ_ТипыПлатформыКлиентСервер.НовыйОписаниеТипаПлатформы
// * Хранилище - Произвольный, Неопределено - Само значение или хранилище, которое можно помещать в данные формы. 
// * Представление - Строка - Как показывать значение пользователю
Функция НовыйКонтейнерЗначения() Экспорт
	Контейнер = Новый Структура;
	Контейнер.Вставить("Тип", "");
	Контейнер.Вставить("ОписаниеТипа", Неопределено);
	Контейнер.Вставить("Хранилище", Неопределено);
	Контейнер.Вставить("Представление", "");
	
	Возврат Контейнер;
КонецФункции

// Новый контейнер значения по типу.
// 
// Параметры:
//  Тип - Тип
// 
// Возвращаемое значение:
//   см. НовыйКонтейнерЗначения
Функция НовыйКонтейнерЗначенияПоТипу(Тип) Экспорт
	ТипыКонтейнеров = ТипыКонтейнеровЗначения();
	
	ОписаниеТипаКонтейнера = УИ_ТипыПлатформыКлиентСервер.ОписаниеТипаПлатформыПоТипу(Тип);
	
	Контейнер = НовыйКонтейнерЗначения();
	Контейнер.ОписаниеТипа = ОписаниеТипаКонтейнера;
	
	Если Тип = Тип("Граница") Тогда
		Контейнер.Тип = ТипыКонтейнеров.Граница;
	ИначеЕсли Тип = Тип("МоментВремени") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.МоментВремени;
	ИначеЕсли Тип = Тип("Тип") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.Тип;
	ИначеЕсли Тип = Тип("ОписаниеТипов") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ОписаниеТипов;
	ИначеЕсли Тип = Тип("Структура") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.Структура;
	ИначеЕсли Тип = Тип("ФиксированнаяСтруктура") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ФиксированнаяСтруктура;
	ИначеЕсли Тип = Тип("Соответствие") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.Соответствие;
	ИначеЕсли Тип = Тип("ФиксированноеСоответствие") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ФиксированноеСоответствие;
	ИначеЕсли Тип = Тип("ТабличныйДокумент") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ТабличныйДокумент;
	ИначеЕсли Тип = Тип("ХранилищеЗначения") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ХранилищеЗначения;
	ИначеЕсли Тип = Тип("СписокЗначений") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.СписокЗначений;
	ИначеЕсли Тип = Тип("Массив") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.Массив;
	ИначеЕсли Тип = Тип("ФиксированныйМассив") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ФиксированныйМассив;
	ИначеЕсли Тип = Тип("Картинка") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.Картинка;
	ИначеЕсли Тип = Тип("ДвоичныеДанные") Тогда 
		Контейнер.Тип = ТипыКонтейнеров.ДвоичныеДанные;
	ИначеЕсли ОписаниеТипаКонтейнера <> Неопределено Тогда
		Если ВРег(ОписаниеТипаКонтейнера.Имя) = "ТАБЛИЦАЗНАЧЕНИЙ" Тогда
			Контейнер.Тип = ТипыКонтейнеров.ТаблицаЗначений;
		ИначеЕсли ВРег(ОписаниеТипаКонтейнера.Имя) = "ДЕРЕВОЗНАЧЕНИЙ" Тогда
			Контейнер.Тип = ТипыКонтейнеров.ДеревоЗначений;
		Иначе
			Контейнер.Тип = ТипыКонтейнеров.Универсальный;
		КонецЕсли;
	Иначе
		Контейнер.Тип = ТипыКонтейнеров.Универсальный;
	КонецЕсли;
	
	Возврат Контейнер;
КонецФункции

// Установить представление контейнера.
// 
// Параметры:
//  КонтейнерЗначения - см. НовыйКонтейнерЗначения
Процедура УстановитьПредставлениеКонтейнера(КонтейнерЗначения) Экспорт
	ТипыКонтейнеров = ТипыКонтейнеровЗначения();
	Если КонтейнерЗначения.Хранилище = Неопределено Тогда
		КонтейнерЗначения.Представление = "";
		Возврат;
	КонецЕсли;
	Если КонтейнерЗначения.Тип = ТипыКонтейнеров.МоментВремени Тогда
		КонтейнерЗначения.Представление = Строка(КонтейнерЗначения.Хранилище.Дата)
										  + "; "
										  + КонтейнерЗначения.Хранилище.Ссылка;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Граница Тогда
		КонтейнерЗначения.Представление = Строка(КонтейнерЗначения.Хранилище.Дата)
										  + " "
										  + КонтейнерЗначения.Хранилище.ВидГраницы;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ТаблицаЗначений Тогда 
		КонтейнерЗначения.Представление = СтрШаблон("Строк: %1 Колонок: %2",
																КонтейнерЗначения.Хранилище.КоличествоСтрок,
																КонтейнерЗначения.Хранилище.КоличествоКолонок);
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ДеревоЗначений Тогда 
		КонтейнерЗначения.Представление = СтрШаблон("ДЗ-Строк: %1 Колонок: %2",
																КонтейнерЗначения.Хранилище.КоличествоСтрок,
																КонтейнерЗначения.Хранилище.КоличествоКолонок);
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Тип Тогда 
		КонтейнерЗначения.Представление = "Тип: "+КонтейнерЗначения.Хранилище.Имя;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ОписаниеТипов Тогда 
		КонтейнерЗначения.Представление = "Типы: "+КонтейнерЗначения.Хранилище.Имя;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Структура Тогда 
		КонтейнерЗначения.Представление = "Структура-"+ КонтейнерЗначения.Хранилище.Ключи;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ФиксированнаяСтруктура Тогда 
		КонтейнерЗначения.Представление = "Фикс.Структура-"+ КонтейнерЗначения.Хранилище.Ключи;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Соответствие Тогда 
		КонтейнерЗначения.Представление = "Соответствие-Ключей-" + КонтейнерЗначения.Хранилище.КоличествоКлючей;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ФиксированноеСоответствие Тогда 
		КонтейнерЗначения.Представление = "Фикс.Соответствие-Ключей-" + КонтейнерЗначения.Хранилище.КоличествоКлючей;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ТабличныйДокумент Тогда
		КонтейнерЗначения.Представление = СтрШаблон("ТабДок-Строк: %1 Колонок: %2",
													КонтейнерЗначения.Хранилище.КоличествоСтрок,
													КонтейнерЗначения.Хранилище.КоличествоКолонок);
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ХранилищеЗначения Тогда 
		КонтейнерЗначения.Представление = "Хранилище: "+КонтейнерЗначения.Хранилище.Тип;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.СписокЗначений Тогда 
		КонтейнерЗначения.Представление = "Список: "+КонтейнерЗначения.Хранилище.Представление;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Массив Тогда 
		КонтейнерЗначения.Представление = "Массив: "+КонтейнерЗначения.Хранилище.Представление;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ФиксированныйМассив Тогда 
		КонтейнерЗначения.Представление = "Фикс.Массив: "+КонтейнерЗначения.Хранилище.Представление;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.Картинка Тогда 
		КонтейнерЗначения.Представление = "Картинка: "+ КонтейнерЗначения.Хранилище.Вид;
	ИначеЕсли КонтейнерЗначения.Тип = ТипыКонтейнеров.ДвоичныеДанные Тогда 
		КонтейнерЗначения.Представление = "Двоичные данные: "+ КонтейнерЗначения.Хранилище.Размер;		
	КонецЕсли;
КонецПроцедуры

// Значение поля с контейнером значения.
// 
// Параметры:
//  СтруктураДанныхФормы - ФормаКлиентскогоПриложения, ДанныеФормыСтруктура, ДанныеФормыЭлементДерева, ДанныеФормыЭлементКоллекции - Структура данных формы
//  ПараметрыХраненияПоляСКонейнером -см. УИ_ОбщегоНазначенияКлиентСервер.НовыйСтруктураХраненияРеквизитаНаФормеСКонейнером
// 
// Возвращаемое значение:
//  Произвольный
Функция ЗначениеПоляСКонтейнеромЗначения(СтруктураДанныхФормы, ПараметрыХраненияПоляСКонейнером) Экспорт
	ЗначениеКонтейнера = СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляКонтейнера];
	ЗначениеПоля = СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляВСтруктуре];
	
	Если ЗначениеКонтейнера = Неопределено Тогда
		Возврат ЗначениеПоля;
	КонецЕсли;
	
	Возврат УИ_ОбщегоНазначения.ЗначениеИзКонтейнераФормы(ЗначениеКонтейнера);
КонецФункции

// Установить значение поля с контейнером.
// 
// Параметры:
//  СтруктураДанныхФормы - ФормаКлиентскогоПриложения, ДанныеФормыСтруктура, ДанныеФормыЭлементДерева, ДанныеФормыЭлементКоллекции - Структура данных формы
//  ПараметрыХраненияПоляСКонейнером -см. УИ_ОбщегоНазначенияКлиентСервер.НовыйСтруктураХраненияРеквизитаНаФормеСКонейнером
//  НовоеЗначение -Произвольный -Новое значение
Процедура УстановитьЗначениеПоляСКонтейнером(СтруктураДанныхФормы, ПараметрыХраненияПоляСКонейнером, НовоеЗначение) Экспорт
	ТипЗначения = ТипЗнч(НовоеЗначение);	

	ТипыДляОписания = Новый Массив;
	ТипыДляОписания.Добавить(ТипЗначения);
	ОписаниеТипа = Новый ОписаниеТипов(ТипыДляОписания);
		
	СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляПредставленияТипаЗначения] = Строка(ОписаниеТипа);
	Если Не ХранитьТипВКонтейнере(ТипЗначения) Тогда
		ТипыДляОписания = Новый Массив;
		ТипыДляОписания.Добавить(ТипЗначения);
		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляТипаЗначения] = ОписаниеТипа;

		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляВСтруктуре] = НовоеЗначение;
		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляКонтейнера] = Неопределено;

	Иначе
		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляТипаЗначения] = ОписаниеТипаСтрока(100);
		
		Контейнер = УИ_ОбщегоНазначения.ЗначениеВКонтейнерДляФормы(НовоеЗначение);

		УстановитьПредставлениеКонтейнера(Контейнер);
		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляКонтейнера] = Контейнер;
		СтруктураДанныхФормы[ПараметрыХраненияПоляСКонейнером.ИмяПоляВСтруктуре] = Контейнер.Представление;
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область НастройкиИмпорта

// Варианты содержимого для импорта.
// 
// Возвращаемое значение:
//  Структура - Варианты содержимого для импорта:
// * Файл - Строка - 
// * Строка - Строка - 
Функция ВариантыСодержимогоДляИмпорта() Экспорт
	Варианты = Новый Структура;
	Варианты.Вставить("Файл", "Файл");
	Варианты.Вставить("Строка", "Строка");
	
	Возврат Варианты;
КонецФункции

// Новый параметры импорта инструмента.
// 
// Возвращаемое значение:
//  Структура - Новый параметры импорта инструмента:
// * Форматы - Массив из см. НовыйФорматИмпортаИнструмента- 
// * ПрочитатьФайлВоВременноеХранилище - Булево
Функция НовыйПараметрыИмпортаИнструмента() Экспорт
	Описание = Новый Структура;
	Описание.Вставить("Форматы", Новый Массив);
	Описание.Вставить("ПрочитатьФайлВоВременноеХранилище", Ложь);
	
	Возврат Описание;
КонецФункции

// Новый формат импорта инструмента.
// 
// Возвращаемое значение:
//  Структура - Новый формат импорта инструмента:
// * Идентификатор - Строка - 
// * Представление - Строка - 
// * ВариантСодержимого - Строка - см. ВариантыСодержимогоДляИмпорта
// * ФильтрФайловДляДиалога - Строка
Функция НовыйФорматИмпортаИнструмента() Экспорт
	Формат = Новый Структура;
	Формат.Вставить("Идентификатор", "");
	Формат.Вставить("Представление", "");
	Формат.Вставить("ВариантСодержимого", "");
	Формат.Вставить("ФильтрФайловДляДиалога", "");
	
	Возврат Формат;
КонецФункции

// Новый результат настроек импорта.
// 
// Возвращаемое значение:
//  Структура - Новый результат настроек импорта:
// * Формат - см. НовыйФорматИмпортаИнструмента 
// * Содержимое - Строка - 
// * ОчиститьДанныеИнструментаПередЗаполнением - Булево
Функция НовыйРезультатНастроекИмпорта() Экспорт
	Описание = Новый Структура;
	Описание.Вставить("Формат", Новый Структура);
	Описание.Вставить("Содержимое", "");
	Описание.Вставить("ОчиститьДанныеИнструментаПередЗаполнением", Ложь);

	Возврат Описание;
КонецФункции

#КонецОбласти

// Описание ОСДля техподдержки.
// 
// Возвращаемое значение:
//  Структура -  Описание ОСДля техподдержки:
// * ВерсияОС - Строка - 
// * Разрядность - Строка - 
// * Процессор - Строка - 
// * Память - Строка - 
Функция ОписаниеОСДляТехподдержки() Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация();
	
	Описание = Новый Структура;
	Описание.Вставить("ВерсияОС", СистемнаяИнформация.ВерсияОС);
	Описание.Вставить("Разрядность", Строка(СистемнаяИнформация.ТипПлатформы));
	Описание.Вставить("Процессор", СистемнаяИнформация.Процессор);
	Описание.Вставить("Память", Строка(СистемнаяИнформация.ОперативнаяПамять));
	
	Возврат Описание;	
КонецФункции

// Текущая версия платформы1 с предприятие.
// 
// Возвращаемое значение:
//  Строка -  Текущая версия платформы 1С предприятие
Функция ТекущаяВерсияПлатформы1СПредприятие() Экспорт

	СистИнфо = Новый СистемнаяИнформация;
	Возврат СистИнфо.ВерсияПриложения;

КонецФункции

// Текущая версия платформы1 с предприятия числом.
// 
// Возвращаемое значение:
//  Число
Функция ТекущаяВерсияПлатформы1СПредприятияЧислом() Экспорт
	Версия = ТекущаяВерсияПлатформы1СПредприятие();
	ЧастиВерсии = СтрРазделить(Версия, ".");

	СтрокаДляЧисла = "";

	Для индекс = 0 По 2 Цикл
		Часть = ЧастиВерсии[индекс];

		СтрокаДляЧисла = СтрокаДляЧисла + УИ_СтроковыеФункцииКлиентСервер.ДополнитьСтроку(Часть, 3);
	КонецЦикла;

	Возврат УИ_СтроковыеФункцииКлиентСервер.СтрокаВЧисло(СтрокаДляЧисла);
КонецФункции

// Тип управляемой формы.
// 
// Возвращаемое значение:
//  Тип -  Тип управляемой формы
Функция ТипУправляемойФормы() Экспорт
	Если ВерсияПлатформыНеМладше_8_3_14() Тогда
		//@skip-check wrong-string-literal-content
		Возврат Тип("ФормаКлиентскогоПриложения")
	Иначе
		Возврат Тип("УправляемаяФорма");
	КонецЕсли;
КонецФункции

// Таблица элемента формы.
// 
// Параметры:
//  Элемент - ПолеФормы, ГруппаФормы, ТаблицаФормы -
// 
// Возвращаемое значение:
//  ТаблицаФормы
// Возвращаемое значение:
//  Неопределено - Элемент не принадлежит таблице формы
Функция ТаблицаЭлементаФормы(Элемент) Экспорт
	ТекЭлемент = Элемент;
	ТипФормы = ТипУправляемойФормы();

	Пока ТипЗнч(ТекЭлемент) <> Тип("ТаблицаФормы") Цикл
		Если ТекЭлемент.Родитель = Неопределено Или ТипЗнч(ТекЭлемент.Родитель) = ТипФормы Тогда

			Возврат Неопределено;
		КонецЕсли;

		ТекЭлемент =  ТекЭлемент.Родитель;
	КонецЦикла;

	Возврат ТекЭлемент;
КонецФункции

// Возвращает код основного языка конфигурации, например "ru".
//
// Возвращаемое значение:
//  Строка - код языка.
//
Функция КодОсновногоЯзыка() Экспорт
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
	Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
#Иначе
		Возврат УИ_ОбщегоНазначенияПовтИсп.КодОсновногоЯзыка();
#КонецЕсли
КонецФункции

// Формирует и выводит сообщение, которое может быть связано с элементом 
// управления формы.
//
// Параметры:
//  ТекстСообщенияПользователю - Строка - текст сообщения.
//  КлючДанных                 - ЛюбаяСсылка - объект или ключ записи информационной базы, к которому это сообщение относится.
//  Поле                       - Строка - наименование реквизита формы.
//  ПутьКДанным                - Строка - путь к данным (путь к реквизиту формы).
//  Отказ                      - Булево - выходной параметр, всегда устанавливается в значение Истина.
//
// Пример:
//
//  1. Для вывода сообщения у поля управляемой формы, связанного с реквизитом объекта:
//  ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
//   НСтр("ru = 'Сообщение об ошибке.'"), ,
//   "ПолеВРеквизитеФормыОбъект",
//   "Объект");
//
//  Альтернативный вариант использования в форме объекта:
//  ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
//   НСтр("ru = 'Сообщение об ошибке.'"), ,
//   "Объект.ПолеВРеквизитеФормыОбъект");
//
//  2. Для вывода сообщения рядом с полем управляемой формы, связанным с реквизитом формы:
//  ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
//   НСтр("ru = 'Сообщение об ошибке.'"), ,
//   "ИмяРеквизитаФормы");
//
//  3. Для вывода сообщения связанного с объектом информационной базы:
//  ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
//   НСтр("ru = 'Сообщение об ошибке.'"), ОбъектИнформационнойБазы, "Ответственный",,Отказ);
//
//  4. Для вывода сообщения по ссылке на объект информационной базы:
//  ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
//   НСтр("ru = 'Сообщение об ошибке.'"), Ссылка, , , Отказ);
//
//  Случаи некорректного использования:
//   1. Передача одновременно параметров КлючДанных и ПутьКДанным.
//   2. Передача в параметре КлючДанных значения типа отличного от допустимых.
//   3. Установка ссылки без установки поля (и/или пути к данным).
//
//@skip-check method-too-many-params
Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = "",
	Знач ПутьКДанным = "", Отказ = Ложь) Экспорт

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = ТекстСообщенияПользователю;
	Сообщение.Поле = Поле;

	ЭтоОбъект = Ложь;

#Если Не ТонкийКлиент И Не ВебКлиент Тогда
	Если КлючДанных <> Неопределено И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
		ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
		ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, "Object.") > 0;
	КонецЕсли;
#КонецЕсли

	Если ЭтоОбъект Тогда
		Сообщение.УстановитьДанные(КлючДанных);
	Иначе
		Сообщение.КлючДанных = КлючДанных;
	КонецЕсли;

	Если Не ПустаяСтрока(ПутьКДанным) Тогда
		Сообщение.ПутьКДанным = ПутьКДанным;
	КонецЕсли;

	Сообщение.Сообщить();

	Отказ = Истина;

КонецПроцедуры

// Добавить массив объектов к сравнению.
// 
// Параметры:
//  Объекты - Массив из ЛюбаяСсылка, СписокЗначений из ЛюбаяСсылка ,ЛюбаяСсылка-Объекты
Процедура ДобавитьМассивОбъектовКСравнению(Объекты) Экспорт
	УИ_ОбщегоНазначенияВызовСервера.ДобавитьМассивОбъектовКСравнению(Объекты);
КонецПроцедуры

// Имя параметра отмененных длительных операций.
// 
// Параметры:
//  Параметры Параметры
// 
// Возвращаемое значение:
//  Строка -  Имя параметра отмененных длительных операций
Функция ИмяПараметраОтмененныхДлительныхОпераций(Параметры) Экспорт

	Возврат "УИ_ОтмененныеДлительныеОперации";
КонецФункции

// Вызывает исключение, если тип значения параметра ИмяПараметра процедуры или функции ИмяПроцедурыИлиФункции
// отличается от ожидаемого.
// Для диагностики типов параметров, передаваемых в процедуры и функции программного интерфейса.
//
// Параметры:
//   ИмяПроцедурыИлиФункции - Строка             - имя процедуры или функции, параметр которой проверяется.
//   ИмяПараметра           - Строка             - имя проверяемого параметра процедуры или функции.
//   ЗначениеПараметра      - Произвольный       - фактическое значение параметра.
//   ОжидаемыеТипы  - ОписаниеТипов, Тип, Массив - тип(ы) параметра процедуры или функции.
//   ОжидаемыеТипыСвойств   - Структура          - если ожидаемый тип - структура, то 
//                                                 в этом параметре можно указать типы ее свойств.
//
Процедура ПроверитьПараметр(Знач ИмяПроцедурыИлиФункции, Знач ИмяПараметра, Знач ЗначениеПараметра, Знач ОжидаемыеТипы,
	Знач ОжидаемыеТипыСвойств = Неопределено) Экспорт

	Контекст = "ОбщегоНазначенияКлиентСервер.ПроверитьПараметр";
	Проверить(ТипЗнч(ИмяПроцедурыИлиФункции) = Тип("Строка"), НСтр(
		"ru = 'Недопустимо значение параметра ИмяПроцедурыИлиФункции'"), Контекст);
	Проверить(ТипЗнч(ИмяПараметра) = Тип("Строка"), НСтр("ru = 'Недопустимо значение параметра ИмяПараметра'"),
		Контекст);

	ЭтоКорректныйТип = ЗначениеОжидаемогоТипа(ЗначениеПараметра, ОжидаемыеТипы);
	Проверить(ЭтоКорректныйТип <> Неопределено, НСтр("ru = 'Недопустимо значение параметра ОжидаемыеТипы'"), Контекст);

	НедопустимыйПараметр = НСтр("ru = 'Недопустимое значение параметра %1 в %2. 
								|Ожидалось: %3; передано значение: %4 (тип %5).'");
	Проверить(ЭтоКорректныйТип, СтрШаблон(НедопустимыйПараметр, ИмяПараметра, ИмяПроцедурыИлиФункции,
		ПредставлениеТипов(ОжидаемыеТипы), ?(ЗначениеПараметра <> Неопределено, ЗначениеПараметра, НСтр(
		"ru = 'Неопределено'")), ТипЗнч(ЗначениеПараметра)));

	Если ТипЗнч(ЗначениеПараметра) = Тип("Структура") И ОжидаемыеТипыСвойств <> Неопределено Тогда

		Проверить(ТипЗнч(ОжидаемыеТипыСвойств) = Тип("Структура"), НСтр(
			"ru = 'Недопустимо значение параметра ИмяПроцедурыИлиФункции'"), Контекст);

		НетСвойства = НСтр("ru = 'Недопустимое значение параметра %1 (Структура) в %2. 
						   |В структуре ожидалось свойство %3 (тип %4).'");
		НедопустимоеСвойство = НСтр("ru = 'Недопустимое значение свойства %1 в параметре %2 (Структура) в %3. 
									|Ожидалось: %4; передано значение: %5 (тип %6).'");
		Для Каждого Свойство Из ОжидаемыеТипыСвойств Цикл

			ОжидаемоеИмяСвойства = Свойство.Ключ;
			ОжидаемыйТипСвойства = Свойство.Значение;
			ЗначениеСвойства = Неопределено;

			Проверить(ЗначениеПараметра.Свойство(ОжидаемоеИмяСвойства, ЗначениеСвойства), СтрШаблон(НетСвойства,
				ИмяПараметра, ИмяПроцедурыИлиФункции, ОжидаемоеИмяСвойства, ОжидаемыйТипСвойства));

			ЭтоКорректныйТип = ЗначениеОжидаемогоТипа(ЗначениеСвойства, ОжидаемыйТипСвойства);
			Проверить(ЭтоКорректныйТип, СтрШаблон(НедопустимоеСвойство, ОжидаемоеИмяСвойства, ИмяПараметра,
				ИмяПроцедурыИлиФункции, ПредставлениеТипов(ОжидаемыеТипы), ?(ЗначениеСвойства <> Неопределено,
				ЗначениеСвойства, НСтр("ru = 'Неопределено'")), ТипЗнч(ЗначениеСвойства)));
		КонецЦикла;
	КонецЕсли;

КонецПроцедуры

// Вызывает исключение с текстом Сообщение, если Условие не равно Истина.
// Применяется для самодиагностики кода.
//
// Параметры:
//   Условие                - Булево - если не равно Истина, то вызывается исключение.
//   КонтекстПроверки       - Строка - например, имя процедуры или функции, в которой выполняется проверка.
//   Сообщение              - Строка - текст сообщения. Если не задан, то исключение вызывается с сообщением по
//                                     умолчанию.
//
Процедура Проверить(Знач Условие, Знач Сообщение = "", Знач КонтекстПроверки = "") Экспорт

	Если Условие <> Истина Тогда
		Если ПустаяСтрока(Сообщение) Тогда
			ТекстИсключения = НСтр("ru = 'Недопустимая операция'"); // Assertion failed
		Иначе
			ТекстИсключения = Сообщение;
		КонецЕсли;
		Если Не ПустаяСтрока(КонтекстПроверки) Тогда
			ТекстИсключения = ТекстИсключения + " " + СтрШаблон(НСтр("ru = 'в %1'"), КонтекстПроверки);
		КонецЕсли;
		ВызватьИсключение ТекстИсключения;
	КонецЕсли;

КонецПроцедуры

// Получает ссылку предопределенного элемента по его полному имени.
// Предопределенные элементы могут содержаться только в следующих объектах:
//   - Справочники;
//   - Планы видов характеристик;
//   - Планы счетов;
//   - Планы видов расчета.
//
// Параметры:
//   ПолноеИмяПредопределенного - Строка - Полный путь к предопределенному элементу, включая его имя.
//     Формат аналогичен функции глобального контекста ПредопределенноеЗначение().
//     Например:
//       "Справочник.ВидыКонтактнойИнформации.EmailПользователя"
//       "ПланСчетов.Хозрасчетный.Материалы"
//       "ПланВидовРасчета.Начисления.ОплатаПоОкладу".
//
// Возвращаемое значение: 
//   ЛюбаяСсылка - ссылка на предопределенный элемент.
//   Неопределено - если предопределенный есть в метаданных, но не создан в ИБ.
//
Функция ПредопределенныйЭлемент(ПолноеИмяПредопределенного) Экспорт

// Используется стандартная функция платформы для получения:
	//  - пустых ссылок; 
	//  - значений перечислений;
	//  - точек маршрута бизнес-процессов.
	Если ".ПУСТАЯССЫЛКА" = ВРег(Прав(ПолноеИмяПредопределенного, 13)) Или "ПЕРЕЧИСЛЕНИЕ." = ВРег(Лев(
		ПолноеИмяПредопределенного, 13)) Или "БИЗНЕСПРОЦЕСС." = ВРег(Лев(ПолноеИмяПредопределенного, 14)) Тогда

		Возврат ПредопределенноеЗначение(ПолноеИмяПредопределенного);
	КонецЕсли;

	// Разбор полного имени предопределенного.
	ЧастиПолногоИмени = СтрРазделить(ПолноеИмяПредопределенного, ".");
	Если ЧастиПолногоИмени.Количество() <> 3 Тогда
		ВызватьИсключение ТекстОшибкиПредопределенноеЗначениеНеНайдено(ПолноеИмяПредопределенного);
	КонецЕсли;

	ПолноеИмяОбъектаМетаданных = ВРег(ЧастиПолногоИмени[0] + "." + ЧастиПолногоИмени[1]);
	ИмяПредопределенного = ЧастиПолногоИмени[2];

	// В зависимости от контекста выполняется обращение к разному кэшу.

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	ПредопределенныеЗначения = УИ_ОбщегоНазначенияПовтИсп.СсылкиПоИменамПредопределенных(ПолноеИмяОбъектаМетаданных);
#Иначе
		ПредопределенныеЗначения = УИ_ОбщегоНазначенияКлиентПовтИсп.СсылкиПоИменамПредопределенных(
			ПолноеИмяОбъектаМетаданных);
#КонецЕсли

	// Если ошибка в имени метаданных.
	Если ПредопределенныеЗначения = Неопределено Тогда
		ВызватьИсключение ТекстОшибкиПредопределенноеЗначениеНеНайдено(ПолноеИмяПредопределенного);
	КонецЕсли;

	// Получение результата из кэша.
	Результат = ПредопределенныеЗначения.Получить(ИмяПредопределенного);

	// Если предопределенного нет в метаданных.
	Если Результат = Неопределено Тогда
		ВызватьИсключение ТекстОшибкиПредопределенноеЗначениеНеНайдено(ПолноеИмяПредопределенного);
	КонецЕсли;

	// Если предопределенный есть в метаданных, но не создан в ИБ.
	Если Результат = Null Тогда
		Возврат Неопределено;
	КонецЕсли;

	Возврат Результат;

КонецФункции

Функция ТекстОшибкиПредопределенноеЗначениеНеНайдено(ПолноеИмяПредопределенного)

	Возврат СтрШаблон(НСтр("ru = 'Предопределенное значение ""%1"" не найдено.'"), ПолноеИмяПредопределенного);

КонецФункции

// Вычисляет переданное выражение, предварительно устанавливая безопасный режим выполнения кода
// и безопасный режим разделения данных для всех разделителей, присутствующих в составе конфигурации.
//
// Параметры:
//  Выражение - Строка - выражение на встроенном языке 1С:Предприятия.
//  ПараметрыМетода - Произвольный - контекст, который требуется для вычисления выражения.
//    В тексте выражения обращение к контексту должно происходить по имени "Параметры".
//    Например, выражение "Параметры.Значение1 = Параметры.Значение2" обращается к значениям
//    "Значение1" и "Значение2" переданные в Параметры, как свойства.
//
// Возвращаемое значение:
//   Произвольный - результат вычисления выражения.
//
// Пример:
//
//  // Пример 1
//  Параметры = Новый Структура;
//  Параметры.Вставить("Значение1", 1);
//  Параметры.Вставить("Значение2", 10);
//  Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме("Параметры.Значение1 = Параметры.Значение2", Параметры);
//
//  // Пример 2
//  Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме("СтандартныеПодсистемыСервер.ВерсияБиблиотеки()");
//
Функция ВычислитьВБезопасномРежиме(Знач Выражение, Знач ПараметрыМетода = Неопределено) Экспорт
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Или ТолстыйКлиентУправляемоеПриложение Тогда
	УстановитьБезопасныйРежим(Истина);
#КонецЕсли	
//	Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
//		МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
//		МассивРазделителей = МодульРаботаВМоделиСервиса.РазделителиКонфигурации();
//	Иначе
//		МассивРазделителей = Новый Массив;
//	КонецЕсли;
	
//	Для Каждого ИмяРазделителя Из МассивРазделителей Цикл
//		
//		УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
//		
//	КонецЦикла;
	
	Возврат Вычислить(Выражение);
	
КонецФункции

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс
// предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки.
#КонецОбласти

#Область СлужебныеПроцедурыИФункции
// содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.
#КонецОбласти


